105 lines
3.0 KiB
JavaScript
105 lines
3.0 KiB
JavaScript
/**
|
|
* Cut input selection into 2 part and return text before selection start
|
|
*/
|
|
export function getBeforeSelectionText(input) {
|
|
const {
|
|
selectionStart
|
|
} = input;
|
|
return input.value.slice(0, selectionStart);
|
|
}
|
|
/**
|
|
* Find the last match prefix index
|
|
*/
|
|
export function getLastMeasureIndex(text) {
|
|
let prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
|
|
const prefixList = Array.isArray(prefix) ? prefix : [prefix];
|
|
return prefixList.reduce((lastMatch, prefixStr) => {
|
|
const lastIndex = text.lastIndexOf(prefixStr);
|
|
if (lastIndex > lastMatch.location) {
|
|
return {
|
|
location: lastIndex,
|
|
prefix: prefixStr
|
|
};
|
|
}
|
|
return lastMatch;
|
|
}, {
|
|
location: -1,
|
|
prefix: ''
|
|
});
|
|
}
|
|
function lower(char) {
|
|
return (char || '').toLowerCase();
|
|
}
|
|
function reduceText(text, targetText, split) {
|
|
const firstChar = text[0];
|
|
if (!firstChar || firstChar === split) {
|
|
return text;
|
|
}
|
|
// Reuse rest text as it can
|
|
let restText = text;
|
|
const targetTextLen = targetText.length;
|
|
for (let i = 0; i < targetTextLen; i += 1) {
|
|
if (lower(restText[i]) !== lower(targetText[i])) {
|
|
restText = restText.slice(i);
|
|
break;
|
|
} else if (i === targetTextLen - 1) {
|
|
restText = restText.slice(targetTextLen);
|
|
}
|
|
}
|
|
return restText;
|
|
}
|
|
/**
|
|
* Paint targetText into current text:
|
|
* text: little@litest
|
|
* targetText: light
|
|
* => little @light test
|
|
*/
|
|
export function replaceWithMeasure(text, measureConfig) {
|
|
const {
|
|
measureLocation,
|
|
prefix,
|
|
targetText,
|
|
selectionStart,
|
|
split
|
|
} = measureConfig;
|
|
// Before text will append one space if have other text
|
|
let beforeMeasureText = text.slice(0, measureLocation);
|
|
if (beforeMeasureText[beforeMeasureText.length - split.length] === split) {
|
|
beforeMeasureText = beforeMeasureText.slice(0, beforeMeasureText.length - split.length);
|
|
}
|
|
if (beforeMeasureText) {
|
|
beforeMeasureText = `${beforeMeasureText}${split}`;
|
|
}
|
|
// Cut duplicate string with current targetText
|
|
let restText = reduceText(text.slice(selectionStart), targetText.slice(selectionStart - measureLocation - prefix.length), split);
|
|
if (restText.slice(0, split.length) === split) {
|
|
restText = restText.slice(split.length);
|
|
}
|
|
const connectedStartText = `${beforeMeasureText}${prefix}${targetText}${split}`;
|
|
return {
|
|
text: `${connectedStartText}${restText}`,
|
|
selectionLocation: connectedStartText.length
|
|
};
|
|
}
|
|
export function setInputSelection(input, location) {
|
|
input.setSelectionRange(location, location);
|
|
/**
|
|
* Reset caret into view.
|
|
* Since this function always called by user control, it's safe to focus element.
|
|
*/
|
|
input.blur();
|
|
input.focus();
|
|
}
|
|
export function validateSearch(text, props) {
|
|
const {
|
|
split
|
|
} = props;
|
|
return !split || text.indexOf(split) === -1;
|
|
}
|
|
export function filterOption(input, _ref) {
|
|
let {
|
|
value = ''
|
|
} = _ref;
|
|
const lowerCase = input.toLowerCase();
|
|
return value.toLowerCase().indexOf(lowerCase) !== -1;
|
|
} |