Skip to content

Instantly share code, notes, and snippets.

@paleite
Last active June 11, 2020 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paleite/ff27ad36ecac7d77a95303bc3bd06267 to your computer and use it in GitHub Desktop.
Save paleite/ff27ad36ecac7d77a95303bc3bd06267 to your computer and use it in GitHub Desktop.
Export css / styles of HTML Element / Node

Export css / styles of HTML Element / Node

Taken from https://stackoverflow.com/a/7756455

Usage

$0.exportStyles()

Code

Element.prototype.exportStyles = (function () {
  // Mapping between tag names and css default values lookup tables. This allows to exclude default values in the result.
  var defaultStylesByTagName = {};

  // Styles inherited from style sheets will not be rendered for elements with these tag names
  var noStyleTags = {
    BASE: true,
    HEAD: true,
    HTML: true,
    META: true,
    NOFRAME: true,
    NOSCRIPT: true,
    PARAM: true,
    SCRIPT: true,
    STYLE: true,
    TITLE: true,
  };

  // This list determines which css default values lookup tables are precomputed at load time
  // Lookup tables for other tag names will be automatically built at runtime if needed
  var tagNames = [
    "A",
    "ABBR",
    "ADDRESS",
    "AREA",
    "ARTICLE",
    "ASIDE",
    "AUDIO",
    "B",
    "BASE",
    "BDI",
    "BDO",
    "BLOCKQUOTE",
    "BODY",
    "BR",
    "BUTTON",
    "CANVAS",
    "CAPTION",
    "CENTER",
    "CITE",
    "CODE",
    "COL",
    "COLGROUP",
    "COMMAND",
    "DATALIST",
    "DD",
    "DEL",
    "DETAILS",
    "DFN",
    "DIV",
    "DL",
    "DT",
    "EM",
    "EMBED",
    "FIELDSET",
    "FIGCAPTION",
    "FIGURE",
    "FONT",
    "FOOTER",
    "FORM",
    "H1",
    "H2",
    "H3",
    "H4",
    "H5",
    "H6",
    "HEAD",
    "HEADER",
    "HGROUP",
    "HR",
    "HTML",
    "I",
    "IFRAME",
    "IMG",
    "INPUT",
    "INS",
    "KBD",
    "KEYGEN",
    "LABEL",
    "LEGEND",
    "LI",
    "LINK",
    "MAP",
    "MARK",
    "MATH",
    "MENU",
    "META",
    "METER",
    "NAV",
    "NOBR",
    "NOSCRIPT",
    "OBJECT",
    "OL",
    "OPTION",
    "OPTGROUP",
    "OUTPUT",
    "P",
    "PARAM",
    "PRE",
    "PROGRESS",
    "Q",
    "RP",
    "RT",
    "RUBY",
    "S",
    "SAMP",
    "SCRIPT",
    "SECTION",
    "SELECT",
    "SMALL",
    "SOURCE",
    "SPAN",
    "STRONG",
    "STYLE",
    "SUB",
    "SUMMARY",
    "SUP",
    "SVG",
    "TABLE",
    "TBODY",
    "TD",
    "TEXTAREA",
    "TFOOT",
    "TH",
    "THEAD",
    "TIME",
    "TITLE",
    "TR",
    "TRACK",
    "U",
    "UL",
    "VAR",
    "VIDEO",
    "WBR",
  ];

  // Precompute the lookup tables.
  for (var i = 0; i < tagNames.length; i++) {
    if (!noStyleTags[tagNames[i]]) {
      defaultStylesByTagName[tagNames[i]] = computeDefaultStyleByTagName(
        tagNames[i]
      );
    }
  }

  function computeDefaultStyleByTagName(tagName) {
    var defaultStyle = {};
    var element = document.body.appendChild(document.createElement(tagName));
    var computedStyle = getComputedStyle(element);
    for (var i = 0; i < computedStyle.length; i++) {
      defaultStyle[computedStyle[i]] = computedStyle[computedStyle[i]];
    }
    document.body.removeChild(element);
    return defaultStyle;
  }

  function getDefaultStyleByTagName(tagName) {
    const _tagName = tagName.toUpperCase();
    if (!defaultStylesByTagName[_tagName]) {
      defaultStylesByTagName[_tagName] = computeDefaultStyleByTagName(_tagName);
    }
    return defaultStylesByTagName[_tagName];
  }

  return function exportStyles() {
    if (this.nodeType !== Node.ELEMENT_NODE) {
      throw new TypeError(
        `The exportStyles method only works on elements, not on ${this.nodeType} nodes.`
      );
    }
    if (noStyleTags[this.tagName]) {
      throw new TypeError(
        `The exportStyles method does not work on ${this.tagName} elements.`
      );
    }
    var styles = {};
    var computedStyle = getComputedStyle(this);
    var defaultStyle = getDefaultStyleByTagName(this.tagName);
    for (var j = 0; j < computedStyle.length; j++) {
      var cssPropName = computedStyle[j];
      if (computedStyle[cssPropName] !== defaultStyle[cssPropName]) {
        styles[cssPropName] = computedStyle[cssPropName];
      }
    }

    var a = ["{"];
    for (var j in styles) {
      if (styles.hasOwnProperty(j)) {
        a[a.length] = `${j}: ${styles[j]};`;
      }
    }
    a[a.length] = "}";
    return a.join("\r\n");
  };
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment