Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | 1198x 253x 250x 259x 69x 940x 836x 410x 2x 408x 408x 10x 398x 214x 214x 214x 214x 518x 518x 3x 69x 3x 69x 3x 69x 5x 2x 3x 3x 1x 2x 69x 5x 5x 3x 3x 2x 69x 69x 2x 2x 2x 2x 2x 2x 2x 2x 69x 8x 2x 6x 2x 1x 1x 4x 1x 3x 69x 3x 3x 3x 3x 3x 3x 3x 69x 8x 8x 15x 3x 5x 69x | import { ReactElement } from "react"; import i18n from '@config/i18n'; import { SearchKeywordHighlightContextSize } from "@config/base"; /** * 将词的第一个字母大写 * @param input 传入的词 */ export function capitalizeFirstLetter(input: string): string { return (input === '' || input == null) ? input : input.charAt(0).toUpperCase() + input.slice(1); } export function stripPackagePart(input: string): string { return (input === '' || input == null) ? input : input.substring(input.lastIndexOf('_') + 1); } export function lowerFirstLetterCase(input: string | null | undefined): string { return (input === '' || input == null) ? "" : input.charAt(0).toLowerCase() + input.slice(1); } export function typeWithPackageToSimpleType(input: string | null | undefined): string { return (input === '' || input == null) ? "" : lowerFirstLetterCase(stripPackagePart(input)); } export const camelCaseToSentence = (word: string): string => word == null ? "" : capitalizeFirstLetter(word .replace(/([A-Z][a-z]+)/g, ' $1') .replace(/([A-Z]{2,})/g, ' $1') .replace(/\s{2,}/g, ' ') .trim()); /** * Change a string to title style, if the parameter is a ReactNode, * then it will be returned back directly * @param title the string or react node to be transfer */ export function humanReadableTitle(title: string | ReactElement): string | ReactElement { return (typeof title != 'string') ? title : camelCaseToSentence(title); } /** * Quote all quotes inside a string using another quote character * @param content the string to be quoted */ export function quoteQuote(content: string | undefined): string | undefined { if (typeof content !== "string") { return content; } if (typeof content.replaceAll !== 'undefined') { return content.replaceAll(`"`, `""`); } else { return content.replace(/`"`/g, `""`); } } /** * Remove package part from a type * @param content the string to be handle */ export function removePackagePart(content: string | undefined): string | undefined { if (typeof content !== 'string') { return content; } const lastIndexOfUnderscore = content.lastIndexOf("_"); if (lastIndexOfUnderscore > 0) { return content.substring(lastIndexOfUnderscore + 1); } return content; } /** * 将包含 java package 的 domainName 修改为界面上显示的不包含 java package, * 且将驼峰词转换为空格分隔的单个单词的形式 * 比如将 tech_muyan_dynamic_form_DynamicForm 转换为 Dynamic Form * @param domainName 输入的 domainName */ export function fullDomainNameToHumanReadable(domainName: string | undefined): string { Iif (domainName == null) return ''; const domainTitle = capitalizeFirstLetter(typeWithPackageToSimpleType(domainName)); const key = `domainTitle:${domainTitle}`; return i18n.t(key); } export function getLinkStrRegExp(): RegExp { return /((http|https|ftp):\/\/[\w?=&.\\/-;#~%-]+(?![\w\s?&.\\/;#~%"=-]*>))/g; } export function getMailStrRegExp(): RegExp { return /([a-zA-Z0-9_.!#$%&'*+\-/=?^_`{|}~]{1,64}@[a-zA-Z0-9-]{1,255}[.][a-zA-Z]{1,233})/g; } /** 生成随机的 id */ export function makeid(length: number): string { const result = []; const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; const charactersLength = characters.length; for (let i = 0; i < length; i++) { result.push(characters.charAt(Math.floor(Math.random() * charactersLength))); } return result.join(''); } /** * Get query parameter from a url * @param urlStr url to parse * @param paramName name of the parameter to parse * @returns value of the parameter */ export function getQueryParam(urlStr: string, paramName: string): string | undefined { const url = new URL(urlStr); const c = url.searchParams.get(paramName); return (c == null) ? undefined : c; } export function trimString(value: string, length: number): string { return value?.length > length ? `${value.substring(0, length)}...` : value; } export const isNotBlank = (word: string | undefined): boolean => { return (word != null && word !== ''); }; export const isBlank = (word: string | undefined): boolean => { return !isNotBlank(word); }; export const isJsonString = (str: string | object): boolean => { if (typeof str === 'object') { return true; } try { JSON.parse(str); } catch (e) { return false; } return true; }; export const formatJson = (jsonString: string): string => { let parsedJson: unknown; try { parsedJson = JSON.parse(jsonString); } catch (error) { console.error("Invalid JSON string provided."); return jsonString; } return JSON.stringify(parsedJson, null, 2); }; export const copyToClipBoard = async(copyMe: string): Promise<void> => { // navigator clipboard 需要https等安全上下文 if (navigator.clipboard && window.isSecureContext) { // navigator clipboard 向剪贴板写文本 return navigator.clipboard.writeText(copyMe); } else { // https://www.cnblogs.com/hellxz/p/15192573.html // https://stackoverflow.com/questions/39501289/in-reactjs-how-to-copy-text-to-clipboard // 创建text area const textArea = document.createElement("textarea"); textArea.value = copyMe; // 使text area不在viewport,同时设置不可见 textArea.style.position = "absolute"; textArea.style.opacity = "0"; textArea.style.left = "-999999px"; textArea.style.top = "-999999px"; document.body.appendChild(textArea); textArea.focus(); textArea.select(); return new Promise((res, rej) => { // 执行复制命令并移除文本框 document.execCommand('copy') ? res() : rej(); textArea.remove(); }); } }; export const stripAbstract = (content: string, searchKeyword: string): string => { const firstIndexOfKeyword = content?.toLowerCase().indexOf(searchKeyword?.toLowerCase()); // 如果 firstIndexOfKeyword 小于 50, 则开始 index 为 0 // 如果 firstIndexOfKeyword 大于 50, 则开始 index 为 firstIndexOfKeyword - 50 // 如果 firstIndexOfKeyword 大于 content.length - 50, 则结束 index 为 content.length // 如果 firstIndexOfKeyword 小于 content.length - 50, 则结束 index 为 firstIndexOfKeyword + 50 // 如果 firstIndexOfKeyword 为 -1, 则开始 index 为 0, 结束 index 为 content.length 和 100 之间更小的值 const cs = SearchKeywordHighlightContextSize; const startIndex = (firstIndexOfKeyword < cs) ? 0 : firstIndexOfKeyword - cs; const endIndex = (firstIndexOfKeyword === 0) ? cs * 2 : (firstIndexOfKeyword < content?.length - cs) ? firstIndexOfKeyword + cs : content?.length; const prefix = ((startIndex > 0) ? "... " : ""); const suffix = ((endIndex < content?.length) ? " ..." : ""); // Abstract 中去除 Html 标签 const absStr = prefix + content?.substring(startIndex, endIndex)?.replace(/<[^>]+>/g, '') + suffix; return absStr; }; export const getRefreshIntervalDisplay = (refreshInterval: number | undefined): string => { if (refreshInterval == null || refreshInterval === 0) { return i18n.t("No auto refresh"); } else if (refreshInterval < 60) { if (refreshInterval === 1) { return refreshInterval + i18n.t("second"); } else { return refreshInterval + i18n.t("seconds"); } } else { if (refreshInterval/60 === 1) { return 1 + i18n.t("minute"); } else { return (refreshInterval/60) + i18n.t("minutes"); } } }; export const getParamsFromUrl = (url: string): Record<string, string> => { Iif (isBlank(url)) { return {} as Record<string, string>; } const normalizedUrl = url.startsWith("http") ? url : `http://${url}`; const searchParams = new URLSearchParams(new URL(normalizedUrl).search); const params = {} as Record<string, string>; for (const [key, value] of searchParams) { params[key] = value; } return params; }; export const startsWithPropKey = (str: string, obj: object): boolean => { const keys = Object.keys(obj); for (let i = 0; i < keys.length; i++) { if (str.startsWith(keys[i])) { return true; } } return false; }; /** * 返回一个字符串的 hash 值 * @param str */ export const stringHash = (str: string): number => { let hash = 0, i, chr; if (str.length === 0) return hash; for (i = 0; i < str.length; i++) { chr = str.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; // Convert to 32bit integer } return hash; }; |