diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index f0cd98e34c..5a7a9d24f9 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -11,6 +11,7 @@ 2, { "SwitchCase": 1 } ], + "default-case": "off", "linebreak-style": [ "warn", "unix" diff --git a/frontend/src/utils/compare-two-string.js b/frontend/src/utils/compare-two-string.js new file mode 100644 index 0000000000..2685940d2c --- /dev/null +++ b/frontend/src/utils/compare-two-string.js @@ -0,0 +1,79 @@ +const isLetterOrNumberReg = (str) => { + return /^[0-9a-zA-Z]+$/.test(str); +}; + +const isAllChineseStr = (str) => { + return /^[\u4E00-\u9FA5]+$/.test(str); +}; + +const splitStringByNumber = (str, sortByNumericalSize = false) => { + let strArr = []; + const REG_STRING_NUMBER_PARTS = /\d+|\D+/g; + const arr = str.match(REG_STRING_NUMBER_PARTS); + for (let i = 0; i < arr.length; i++) { + const splitStr = arr[i]; + if (isNaN(splitStr)) { + strArr = strArr.concat(splitStr.split('')); + } else { + // Whether to split numbers + if (!sortByNumericalSize) { + strArr = strArr.concat(splitStr.split('')); + } else { + strArr.push(splitStr); + } + } + } + return strArr; +}; + +const compareTwoString = (a, b, sortByNumericalSize = true) => { + // all the string is number or letter + if (isLetterOrNumberReg(a) && isLetterOrNumberReg(b)) { + return a.localeCompare(b, 'zh-Hans-CN', { numeric: true }); + } + + // all the string is chinese string + if (isAllChineseStr(a) && isAllChineseStr(b)) { + return a.localeCompare(b, 'zh-Hans-CN', { numeric: true }); + } + + const arrA = splitStringByNumber(a, sortByNumericalSize); + const arrB = splitStringByNumber(b, sortByNumericalSize); + + let result = 0; + const length = Math.min(arrA.length, arrB.length); + for (let i = 0; i < length; i++) { + const charA = arrA[i]; + const charB = arrB[i]; + // charB is chinese + if (!isAllChineseStr(charA) && isAllChineseStr(charB)) { + return -1; + } + + // charA is chinese + if (isAllChineseStr(charA) && !isAllChineseStr(charB)) { + return 1; + } + + // charA and charB all chinese + if (isAllChineseStr(charA) && isAllChineseStr(charB)) { + result = charA.localeCompare(charB, 'zh-Hans-CN'); + } else { + // charA and charB all not chinese + result = charA.localeCompare(charB, 'zh-Hans-CN', { numeric: true }); + } + + if (result !== 0) { + return result; + } + } + + // result === 0; + if (arrA.length > arrB.length) return 1; + if (arrA.length < arrB.length) return -1; + return 0; +}; + +export { + compareTwoString +}; diff --git a/frontend/src/utils/utils.js b/frontend/src/utils/utils.js index e901e56f5e..5ffca047ca 100644 --- a/frontend/src/utils/utils.js +++ b/frontend/src/utils/utils.js @@ -1,9 +1,9 @@ import { mediaUrl, gettext, serviceURL, siteRoot, isPro, enableFileComment, fileAuditEnabled, canGenerateShareLink, canGenerateUploadLink, shareLinkPasswordMinLength, username, folderPermEnabled, onlyofficeConverterExtensions, enableOnlyoffice } from './constants'; -import { strChineseFirstPY } from './pinyin-by-unicode'; import TextTranslation from './text-translation'; import React from 'react'; import toaster from '../components/toast'; import PermissionDeniedTip from '../components/permission-denied-tip'; +import { compareTwoString } from './compare-two-string'; export const Utils = { @@ -879,28 +879,7 @@ export const Utils = { // if wordA >= wordB, return 1 // if wordA < wordB, return -1 - var a_val, b_val, - a_uni = wordA.charCodeAt(0), - b_uni = wordB.charCodeAt(0); - - if ((19968 < a_uni && a_uni < 40869) && (19968 < b_uni && b_uni < 40869)) { - // both are chinese words - a_val = strChineseFirstPY.charAt(a_uni - 19968).toLowerCase(); - b_val = strChineseFirstPY.charAt(b_uni - 19968).toLowerCase(); - } else if ((19968 < a_uni && a_uni < 40869) && !(19968 < b_uni && b_uni < 40869)) { - // a is chinese and b is english - return 1; - } else if (!(19968 < a_uni && a_uni < 40869) && (19968 < b_uni && b_uni < 40869)) { - // a is english and b is chinese - return -1; - } else { - // both are english words - a_val = wordA.toLowerCase(); - b_val = wordB.toLowerCase(); - return this.compareStrWithNumbersIn(a_val, b_val); - } - - return a_val >= b_val ? 1 : -1; + return compareTwoString(wordA, wordB); }, // compare two strings which may have digits in them