Skip to content

Commit

Permalink
Optimize the code
Browse files Browse the repository at this point in the history
  • Loading branch information
WunderBart committed Oct 12, 2023
1 parent 0ced304 commit b799705
Showing 1 changed file with 70 additions and 79 deletions.
149 changes: 70 additions & 79 deletions packages/components/src/autocomplete/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,101 +218,92 @@ export function useAutocomplete( {
return;
}

const lastTriggerPrefix = completers.reduce< string | null >(
( lastTrigger, { triggerPrefix } ) => {
const triggerIndex = textContent.lastIndexOf( triggerPrefix );
// Find the completer with the highest triggerPrefix index in the
// textContent.
const completer = completers.reduce< WPCompleter | null >(
( lastTrigger, currentCompleter ) => {
const triggerIndex = textContent.lastIndexOf(
currentCompleter.triggerPrefix
);
const lastTriggerIndex =
lastTrigger !== null
? textContent.lastIndexOf( lastTrigger )
? textContent.lastIndexOf( lastTrigger.triggerPrefix )
: -1;

return triggerIndex > lastTriggerIndex
? triggerPrefix
? currentCompleter
: lastTrigger;
},
null
);

const completer = completers.find(
( { triggerPrefix, allowContext } ) => {
if ( triggerPrefix !== lastTriggerPrefix ) {
return false;
}
if ( ! completer ) {
if ( autocompleter ) reset();
return;
}

const index = textContent.lastIndexOf( triggerPrefix );
const { allowContext, triggerPrefix } = completer;
const triggerIndex = textContent.lastIndexOf( triggerPrefix );
const textWithoutTrigger = textContent.slice(
triggerIndex + triggerPrefix.length
);

if ( index === -1 ) {
return false;
}
const tooDistantFromTrigger = textWithoutTrigger.length > 50; // 50 chars seems to be a good limit.
// This is a final barrier to prevent the effect from completing with
// an extremely long string, which causes the editor to slow-down
// significantly. This could happen, for example, if `matchingWhileBackspacing`
// is true and one of the "words" end up being too long. If that's the case,
// it will be caught by this guard.
if ( tooDistantFromTrigger ) return;

const mismatch = filteredOptions.length === 0;
const wordsFromTrigger = textWithoutTrigger.split( /\s/ );
// We need to allow the effect to run when not backspacing and if there
// was a mismatch. i.e when typing a trigger + the match string or when
// clicking in an existing trigger word on the page. We do that if we
// detect that we have one word from trigger in the current textual context.
//
// Ex.: "Some text @a" <-- "@a" will be detected as the trigger word and
// allow the effect to run. It will run until there's a mismatch.
const hasOneTriggerWord = wordsFromTrigger.length === 1;
// This is used to allow the effect to run when backspacing and if
// "touching" a word that "belongs" to a trigger. We consider a "trigger
// word" any word up to the limit of 3 from the trigger character.
// Anything beyond that is ignored if there's a mismatch. This allows
// us to "escape" a mismatch when backspacing, but still imposing some
// sane limits.
//
// Ex: "Some text @marcelo sekkkk" <--- "kkkk" caused a mismatch, but
// if the user presses backspace here, it will show the completion popup again.
const matchingWhileBackspacing =
backspacing.current && wordsFromTrigger.length <= 3;

if ( mismatch && ! ( matchingWhileBackspacing || hasOneTriggerWord ) ) {
return;
}

const textWithoutTrigger = textContent.slice(
index + triggerPrefix.length
);
const textAfterSelection = getTextContent(
slice( record, undefined, getTextContent( record ).length )
);

const tooDistantFromTrigger = textWithoutTrigger.length > 50; // 50 chars seems to be a good limit.
// This is a final barrier to prevent the effect from completing with
// an extremely long string, which causes the editor to slow-down
// significantly. This could happen, for example, if `matchingWhileBackspacing`
// is true and one of the "words" end up being too long. If that's the case,
// it will be caught by this guard.
if ( tooDistantFromTrigger ) return false;

const mismatch = filteredOptions.length === 0;
const wordsFromTrigger = textWithoutTrigger.split( /\s/ );
// We need to allow the effect to run when not backspacing and if there
// was a mismatch. i.e when typing a trigger + the match string or when
// clicking in an existing trigger word on the page. We do that if we
// detect that we have one word from trigger in the current textual context.
//
// Ex.: "Some text @a" <-- "@a" will be detected as the trigger word and
// allow the effect to run. It will run until there's a mismatch.
const hasOneTriggerWord = wordsFromTrigger.length === 1;
// This is used to allow the effect to run when backspacing and if
// "touching" a word that "belongs" to a trigger. We consider a "trigger
// word" any word up to the limit of 3 from the trigger character.
// Anything beyond that is ignored if there's a mismatch. This allows
// us to "escape" a mismatch when backspacing, but still imposing some
// sane limits.
//
// Ex: "Some text @marcelo sekkkk" <--- "kkkk" caused a mismatch, but
// if the user presses backspace here, it will show the completion popup again.
const matchingWhileBackspacing =
backspacing.current && wordsFromTrigger.length <= 3;

if (
mismatch &&
! ( matchingWhileBackspacing || hasOneTriggerWord )
) {
return false;
}

const textAfterSelection = getTextContent(
slice( record, undefined, getTextContent( record ).length )
);
if (
allowContext &&
! allowContext(
textContent.slice( 0, triggerIndex ),
textAfterSelection
)
) {
return;
}

if (
allowContext &&
! allowContext(
textContent.slice( 0, index ),
textAfterSelection
)
) {
return false;
}

if (
/^\s/.test( textWithoutTrigger ) ||
/\s\s+$/.test( textWithoutTrigger )
) {
return false;
}

return /[\u0000-\uFFFF]*$/.test( textWithoutTrigger );
}
);
if (
/^\s/.test( textWithoutTrigger ) ||
/\s\s+$/.test( textWithoutTrigger )
) {
return;
}

if ( ! completer ) {
if ( autocompleter ) reset();
if ( ! /[\u0000-\uFFFF]*$/.test( textWithoutTrigger ) ) {
return;
}

Expand Down

0 comments on commit b799705

Please sign in to comment.