/* 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/. */
/** * Called when a character is typed in a value editor. This decides * whether to advance or not, first by checking to see if ";" was * typed, and then by lexing the input and seeing whether the ";" * would be a terminator at this point. * * @param {number} keyCode * Key code to be checked. * @param {string} aValue * Current text editor value. * @param {number} insertionPoint * The index of the insertion point. * @return {Boolean} True if the focus should advance; false if * the character should be inserted.
*/ function advanceValidate(keyCode, value, insertionPoint) { // Only ";" has special handling here. if (keyCode !== KeyCodes.DOM_VK_SEMICOLON) { returnfalse;
}
// Insert the character provisionally and see what happens. If we // end up with a ";" symbol token, then the semicolon terminates the // value. Otherwise it's been inserted in some spot where it has a // valid meaning, like a comment or string.
value = value.slice(0, insertionPoint) + ";" + value.slice(insertionPoint); const lexer = new InspectorCSSParserWrapper(value); while (true) { const token = lexer.nextToken(); if (token.endOffset > insertionPoint) { if (token.tokenType === "Semicolon") { // The ";" is a terminator. returntrue;
} // The ";" is not a terminator in this context. break;
}
} returnfalse;
}
/** * Append a text node to an element. * * @param {Element} parent * The parent node. * @param {string} text * The text content for the text node.
*/ function appendText(parent, text) {
parent.appendChild(parent.ownerDocument.createTextNode(text));
}
/** * Event handler that causes a blur on the target if the input has * multiple CSS properties as the value.
*/ function blurOnMultipleProperties(cssProperties) { return e => {
setTimeout(() => { const props = parseDeclarations(cssProperties.isKnown, e.target.value); if (props.length > 1) {
e.target.blur();
}
}, 0);
};
}
/** * Create a child element with a set of attributes. * * @param {Element} parent * The parent node. * @param {string} tagName * The tag name. * @param {object} attributes * A set of attributes to set on the node.
*/ function createChild(parent, tagName, attributes = {}) { const elt = parent.ownerDocument.createElementNS(HTML_NS, tagName); for (const attr in attributes) { if (attributes.hasOwnProperty(attr)) { if (attr === "textContent") {
elt.textContent = attributes[attr];
} elseif (attr === "child") {
elt.appendChild(attributes[attr]);
} else {
elt.setAttribute(attr, attributes[attr]);
}
}
}
parent.appendChild(elt); return elt;
}
/** * Retrieve the content of a longString (via a promise resolving a LongStringActor). * * @param {Promise} longStringActorPromise * promise expected to resolve a LongStringActor instance * @return {Promise} promise resolving with the retrieved string as argument
*/
async function getLongString(longStringActorPromise) { try { const longStringActor = await longStringActorPromise; const string = await longStringActor.string();
longStringActor.release().catch(console.error); return string;
} catch (e) {
console.error(e); return undefined;
}
}
/** * Returns a selector of the Element Rep from the grip. This is based on the * getElements() function in our devtools-reps component for a ElementNode. * * @param {Object} grip * Grip-like object that can be used with Reps. * @return {String} selector of the element node.
*/ function getSelectorFromGrip(grip) { const {
attributes,
nodeName,
isAfterPseudoElement,
isBeforePseudoElement,
isMarkerPseudoElement,
} = grip.preview;
/** * Log the provided error to the console and return a rejected Promise for * this error. * * @param {Error} error * The error to log * @return {Promise} A rejected promise
*/ function promiseWarn(error) {
console.error(error); return Promise.reject(error);
}
/** * While waiting for a reps fix in https://github.com/firefox-devtools/reps/issues/92, * translate nodeFront to a grip-like object that can be used with an ElementNode rep. * * @params {NodeFront} nodeFront * The NodeFront for which we want to create a grip-like object. * @returns {Object} a grip-like object that can be used with Reps.
*/ function translateNodeFrontToGrip(nodeFront) { const { attributes } = nodeFront;
// The main difference between NodeFront and grips is that attributes are treated as // a map in grips and as an array in NodeFronts. const attributesMap = {}; for (const { name, value } of attributes) {
attributesMap[name] = value;
}
return {
actor: nodeFront.actorID,
preview: {
attributes: attributesMap,
attributesLength: attributes.length,
isAfterPseudoElement: nodeFront.isAfterPseudoElement,
isBeforePseudoElement: nodeFront.isBeforePseudoElement,
isMarkerPseudoElement: nodeFront.isMarkerPseudoElement, // All the grid containers are assumed to be in the DOM tree.
isConnected: true, // nodeName is already lowerCased in Node grips
nodeName: nodeFront.nodeName.toLowerCase(),
nodeType: nodeFront.nodeType,
},
};
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.