Files
sousa-gecko/devtools/client/shared/inplace-editor-utils/autocomplete-anchor-function.mjs
T
Nicolas Chevobbe 0b3ac95a9d Bug 2023114 - [devtools] Add autocomplete for anchor() in Rules view. r=devtools-reviewers,jdescottes.
Add a dedicated autocomplete module for the InplaceEditor.
This doesn't require any work on the Rules view side, as we're already
getting anchor names from the previous patch in the stack.

Differential Revision: https://phabricator.services.mozilla.com/D287965
2026-03-20 10:25:05 +00:00

94 lines
2.4 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const ANCHOR_SIDES = [
"bottom",
"center",
"end",
"inside",
"left",
"outside",
"right",
"self-end",
"self-start",
"start",
"top",
];
/**
* Compute the autocomplete data for the passed anchor() function.
*
* @param {object} params
* @param {Array<InspectorCSSToken>} params.functionTokens: The tokens representing the
* function parameters (i.e. what's inside the parenthesis)
* @param {Array<string>} params.anchorNames: A list of anchor names.
* @returns {object} Returns an object of the following shape:
* - {Array<string>} list: The list of autocomplete items
*/
export function getAutocompleteDataForAnchorFunction({
functionTokens,
anchorNames,
}) {
// <anchor()> = anchor( <anchor-name>? && <anchor-side>, <length-percentage>? )
// <anchor-side> = inside | outside
// | top | left | right | bottom
// | start | end | self-start | self-end
// | <percentage> | center
const list = [];
const lastToken = functionTokens.at(-1);
const isLastTokenComplete = !!lastToken?.complete;
let hasComma = false;
// For the first token of the function, we can have an anchor name or an anchor side
let waitingForAnchorSide = true;
let waitingForAnchorName = true;
for (const token of functionTokens) {
// Don't handle last token if it's not complete
if (token === lastToken && !isLastTokenComplete) {
continue;
}
const { tokenType, text } = token;
if (
!hasComma &&
waitingForAnchorName &&
tokenType === "Ident" &&
text.startsWith("--")
) {
waitingForAnchorName = false;
continue;
}
if (
!hasComma &&
waitingForAnchorSide &&
tokenType === "Ident" &&
ANCHOR_SIDES.includes(text)
) {
waitingForAnchorSide = false;
continue;
}
// Once we have a comma, we don't want to wait for anything
if (tokenType === "Comma") {
hasComma = true;
waitingForAnchorSide = false;
waitingForAnchorName = false;
continue;
}
}
if (waitingForAnchorName && anchorNames) {
list.push(...anchorNames);
}
if (waitingForAnchorSide) {
list.push(...ANCHOR_SIDES);
}
return { list };
}