summaryrefslogtreecommitdiffstats
path: root/devtools/client/inspector/markup/utils.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/inspector/markup/utils.js')
-rw-r--r--devtools/client/inspector/markup/utils.js135
1 files changed, 135 insertions, 0 deletions
diff --git a/devtools/client/inspector/markup/utils.js b/devtools/client/inspector/markup/utils.js
new file mode 100644
index 000000000..8fab9d963
--- /dev/null
+++ b/devtools/client/inspector/markup/utils.js
@@ -0,0 +1,135 @@
+/* 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 {Node} foregroundElt
+ * The element to set the matching foreground color on.
+ * Optional. This will equal backgroundElt if not set.
+ */
+function flashElementOn(backgroundElt, foregroundElt = backgroundElt) {
+ if (!backgroundElt || !foregroundElt) {
+ return;
+ }
+
+ // Make sure the animation class is not here
+ backgroundElt.classList.remove("flash-out");
+
+ // Change the background
+ backgroundElt.classList.add("theme-bg-contrast");
+
+ 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 reomve the highlighted background color on.
+ * @param {Node} foregroundElt
+ * The element to remove the matching foreground color on.
+ * Optional. This will equal backgroundElt if not set.
+ */
+function flashElementOff(backgroundElt, foregroundElt = backgroundElt) {
+ if (!backgroundElt || !foregroundElt) {
+ return;
+ }
+
+ // Add the animation class to smoothly remove the background
+ backgroundElt.classList.add("flash-out");
+
+ // Remove the background
+ backgroundElt.classList.remove("theme-bg-contrast");
+
+ foregroundElt.classList.remove("theme-fg-contrast");
+ [].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) {
+ let elementRect = element.getBoundingClientRect();
+ let 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();
+
+ let 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
+ let el = parseAndGetNode("<svg " + attr + "></svg>") ||
+ parseAndGetNode("<svg " + attr + "\"></svg>") ||
+ parseAndGetNode("<svg " + attr + "'></svg>");
+
+ let div = doc.createElement("div");
+ let attributes = [];
+ for (let {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;
+}
+
+/**
+ * Truncate the string and add ellipsis to the middle of the string.
+ */
+function truncateString(str, maxLength) {
+ if (!str || str.length <= maxLength) {
+ return str;
+ }
+
+ return str.substring(0, Math.ceil(maxLength / 2)) +
+ "…" +
+ str.substring(str.length - Math.floor(maxLength / 2));
+}
+
+module.exports = {
+ flashElementOn,
+ flashElementOff,
+ getAutocompleteMaxWidth,
+ parseAttributeValues,
+ truncateString,
+};