diff options
Diffstat (limited to 'devtools/client/inspector/markup/utils.js')
-rw-r--r-- | devtools/client/inspector/markup/utils.js | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/devtools/client/inspector/markup/utils.js b/devtools/client/inspector/markup/utils.js new file mode 100644 index 0000000000..06609676a5 --- /dev/null +++ b/devtools/client/inspector/markup/utils.js @@ -0,0 +1,136 @@ +/* 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/. */ + +"use strict"; + +/** + * Apply a 'flashed' background and foreground color to elements. Intended + * to be used with flashElementOff as a way of drawing attention to an element. + * + * @param {Node} backgroundElt + * The element to set the highlighted background color on. + * @param {Object} options + * @param {Node} options.foregroundElt + * The element to set the matching foreground color on. This will equal + * backgroundElt if not set. + * @param {String} options.backgroundClass + * The background highlight color class to set on the element. + */ +function flashElementOn( + backgroundElt, + { foregroundElt = backgroundElt, backgroundClass = "theme-bg-contrast" } = {} +) { + if (!backgroundElt || !foregroundElt) { + return; + } + + // Make sure the animation class is not here + backgroundElt.classList.remove("flash-out"); + + // Change the background + backgroundElt.classList.add(backgroundClass); + + foregroundElt.classList.add("theme-fg-contrast"); + [].forEach.call( + foregroundElt.querySelectorAll("[class*=theme-fg-color]"), + span => span.classList.add("theme-fg-contrast") + ); +} + +/** + * Remove a 'flashed' background and foreground color to elements. + * See flashElementOn. + * + * @param {Node} backgroundElt + * The element to remove the highlighted background color on. + * @param {Object} options + * @param {Node} options.foregroundElt + * The element to remove the matching foreground color on. This will equal + * backgroundElt if not set. + * @param {String} options.backgroundClass + * The background highlight color class to remove on the element. + */ +function flashElementOff( + backgroundElt, + { foregroundElt = backgroundElt, backgroundClass = "theme-bg-contrast" } = {} +) { + if (!backgroundElt || !foregroundElt) { + return; + } + + // Add the animation class to smoothly remove the background + backgroundElt.classList.add("flash-out"); + + // Remove the background + backgroundElt.classList.remove(backgroundClass); + + foregroundElt.classList.remove("theme-fg-contrast"); + // Make sure the foreground animation class is removed + foregroundElt.classList.remove("flash-out"); + [].forEach.call( + foregroundElt.querySelectorAll("[class*=theme-fg-color]"), + span => span.classList.remove("theme-fg-contrast") + ); +} + +/** + * Retrieve the available width between a provided element left edge and a container right + * edge. This used can be used as a max-width for inplace-editor (autocomplete) widgets + * replacing Editor elements of the the markup-view; + */ +function getAutocompleteMaxWidth(element, container) { + const elementRect = element.getBoundingClientRect(); + const containerRect = container.getBoundingClientRect(); + return containerRect.right - elementRect.left - 2; +} + +/** + * Parse attribute names and values from a string. + * + * @param {String} attr + * The input string for which names/values are to be parsed. + * @param {HTMLDocument} doc + * A document that can be used to test valid attributes. + * @return {Array} + * An array of attribute names and their values. + */ +function parseAttributeValues(attr, doc) { + attr = attr.trim(); + + const parseAndGetNode = str => { + return new DOMParser().parseFromString(str, "text/html").body.childNodes[0]; + }; + + // Handle bad user inputs by appending a " or ' if it fails to parse without + // them. Also note that a SVG tag is used to make sure the HTML parser + // preserves mixed-case attributes + const el = + parseAndGetNode("<svg " + attr + "></svg>") || + parseAndGetNode("<svg " + attr + '"></svg>') || + parseAndGetNode("<svg " + attr + "'></svg>"); + + const div = doc.createElement("div"); + const attributes = []; + for (const { name, value } of el.attributes) { + // Try to set on an element in the document, throws exception on bad input. + // Prevents InvalidCharacterError - "String contains an invalid character". + try { + div.setAttribute(name, value); + attributes.push({ name, value }); + } catch (e) { + // This may throw exceptions on bad input. + // Prevents InvalidCharacterError - "String contains an invalid + // character". + } + } + + return attributes; +} + +module.exports = { + flashElementOn, + flashElementOff, + getAutocompleteMaxWidth, + parseAttributeValues, +}; |