UNPKG

cssom

Version:

CSS Object Model implementation and CSS parser

283 lines (261 loc) 5.69 kB
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>CSSOM.js parse method</title> <script> var exports = {}; function require(){ return exports; } </script> <script src="../lib/CSSStyleDeclaration.js"></script> <script src="../lib/CSSRule.js"></script> <script src="../lib/CSSStyleRule.js"></script> <script src="../lib/CSSImportRule.js"></script> <script src="../lib/MediaList.js"></script> <script src="../lib/CSSMediaRule.js"></script> <script src="../lib/StyleSheet.js"></script> <script src="../lib/CSSStyleSheet.js"></script> <script src="../lib/parse.js"></script> <script> window.CSSOM = exports; </script> <style type="text/css"> html, body { background: #333; color: #EEE; font: 12px sans-serif; margin: 0; height: 100%; } body { padding-bottom: 1.7em; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } table { width: 100%; table-layout: fixed; margin: 0 auto; } td { vertical-align: top; } h1 { font: normal 1em sans-serif; display: inline; } #labels { color: #FFE992; width: 66%; } #labels td { width: 50%; text-align: center; } #labels td::before { content: '↱ '; color: #998e62; position: relative; top: .4em; } #labels td::after { content: ' ↴'; color: #998e62; position: relative; top: .4em; } #content { width: 100%; height: 100%; } #content td { width: 33%; } #content td + td { padding-left: 1%; } #output span { color: #666; } .style-cell textarea { width: 99%; height: 100%; font: 12px monospace; white-space: pre-wrap; } .serialized-cell { border-left: 1px solid #363636; } #message { visibility: hidden; } .error #message { visibility: visible; position: absolute; top: 0; left: 34%; padding: 1em; background: black; color: #e34343; font-size: 24px; } </style> </head> <body> <table id="labels"> <tr><td><h1>CSSOM.parse</h1></td><td>.toString</td></tr> </table> <table id="content"> <tr> <td class="style-cell"> <textarea id="style" spellcheck="false" rows="40">img { border: none }</textarea></td> <td class="output-cell"><pre id="output"></pre></td> <td class="serialized-cell"><pre id="serialized"></pre></td> </tr> </table> <div id="message"></div> <script defer> /** * @param {number} depth * @return {string} */ function makeIndent(depth) { var INDENT = ' '; if (depth == 1) { return INDENT; } else if (depth < 1) { return ''; } if (depth in makeIndent.cache) { return makeIndent.cache[depth]; } else { var result = INDENT; for (var i = depth; --i;) { result += INDENT; } makeIndent.cache[depth] = result; return result; } } makeIndent.cache = {}; /** * buildPath(2) -> '../..' * @param {number} level * @return {string} */ function buildPath(level) { if (level == 0) { return '.'; } else { var result = '..'; for (var i = 1; i < level; i++) { result += '/..'; } return result; } } /** * stringifyObjectKey('color') -> 'color' * stringifyObjectKey('background-color') -> '"background-color"' * @param {string} key * @return {string} */ function stringifyObjectKey(key) { return /^[a-zA-Z_$][A-Za-z0-9_$]*$/.test(key) ? key : '"' + escapeDoubleQuotes(key) + '"'; } /** * @param {string} string * @return {string} * @see http://stackoverflow.com/questions/7382115/escape-quotes-in-a-string-with-backslash */ function escapeDoubleQuotes(string) { return string.replace(/(\\*)(")/g, function(all, backslashes, quote) { return backslashes.length % 2 ? all : backslashes + '\\' + quote; }); } /** * @param {Object} object * @param {number} [depth] * @param {Array} [stack] * @return {string} */ function inspect(object, depth, stack) { depth ? depth++ : (depth = 1); stack = stack || (stack = []); switch (typeof object) { case 'object': var level = stack.indexOf(object); if (level != -1) { return buildPath(level); } stack = [object].concat(stack); var properties = []; var indent = makeIndent(depth); for (var key in object) { if (object.hasOwnProperty(key)) { properties.push(indent + stringifyObjectKey(key) + '<span>: </span>' + inspect(object[key], depth, stack)); } } var indentInside = makeIndent(depth - 1); return '<span>{</span>\n' + properties.join('<span>,</span>\n') + '\n' + indentInside + '<span>}</span>'; case 'string': return '"' + object + '"'; default: return object.toString(); } } var errors = []; if (!("__defineGetter__" in {})) { errors.push("Object.prototype.__defineGetter__ isn’t supported"); } if (errors.length) { document.getElementById("message").innerHTML = errors.join("<br>"); document.body.className = "error"; throw errors.join("\n\n"); } var style = document.getElementById("style"); var output = document.getElementById("output"); var serialized = document.getElementById("serialized"); function outputUpdated(){ var value = style.value; if (value != style.prevValue) { var css = CSSOM.parse(value); output.innerHTML = inspect(css); serialized.innerHTML = css.toString(); style.prevValue = value; } } function hashChanged(){ var hash = location.hash; var splitted = hash.split("="); if (splitted.length < 2) { return; } var name = splitted[0]; var value = splitted[1]; if (name == "#css") { style.value = decodeURIComponent(value); outputUpdated(); } } hashChanged(); outputUpdated(); window.onhashchange = hashChanged; style.onkeyup = style.onpaste = function changed(){ outputUpdated(); }; style.onchange = function updateLocation(){ location.hash = "css=" + encodeURIComponent(style.value); }; </script> </body> </html>