Index: third_party/polymer/v0_8/components/polymer/src/lib/expr/style-auditor.html |
diff --git a/third_party/polymer/v0_8/components/polymer/src/lib/expr/style-auditor.html b/third_party/polymer/v0_8/components/polymer/src/lib/expr/style-auditor.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..576055e5be6212530091b2d0c195f84a56245b21 |
--- /dev/null |
+++ b/third_party/polymer/v0_8/components/polymer/src/lib/expr/style-auditor.html |
@@ -0,0 +1,123 @@ |
+<script> |
+addEventListener('WebComponentsReady', function() { |
+ |
+ // given a list of elements, produce a report of rules that |
+ // match those elements. |
+ var auditor = { |
+ |
+ matchesForDocument: function(elements) { |
+ var info = []; |
+ this.documentSheets.forEach(function(sheet) { |
+ var list = this.matchesForSheet(sheet, elements); |
+ if (list.length) { |
+ info.push({sheet: sheet, rules: list}); |
+ } |
+ }, this); |
+ return info; |
+ }, |
+ |
+ // TODO(sorvell): support stylesheets inside HTMLImports |
+ documentSheets: Array.prototype.filter.call(document.styleSheets, |
+ function(sheet) { |
+ return !sheet.ownerNode.hasAttribute('scope'); |
+ } |
+ ), |
+ |
+ matchesForSheet: function(sheet, elements) { |
+ var info = []; |
+ Array.prototype.forEach.call(sheet.cssRules, function(rule) { |
+ var list = this.matchesForRule(rule, elements); |
+ if (list.length) { |
+ info.push({selector: rule.selectorText, elements: list}); |
+ } |
+ }, this); |
+ return info; |
+ }, |
+ |
+ matchesForRule: function(rule, list) { |
+ var info = []; |
+ list.forEach(function(i) { |
+ var elements = i.elements.filter(function(e) { |
+ return matchesSelector.call(e, rule.selectorText); |
+ }); |
+ if (elements.length) { |
+ info.push({host: i.host, elements: elements}); |
+ } |
+ }); |
+ return info; |
+ } |
+ |
+ }; |
+ |
+ var p = Element.prototype; |
+ var matchesSelector = p.matches || p.matchesSelector || |
+ p.mozMatchesSelector || p.msMatchesSelector || |
+ p.oMatchesSelector || p.webkitMatchesSelector; |
+ |
+ |
+ // crawl the document and return a list of custom elements with shadyRoots |
+ // and their scoped contents |
+ var crawler = { |
+ // list of elements: array of {host, elements} |
+ list: function() { |
+ var list = []; |
+ var elements = this.elementsWithShadyRoot(); |
+ elements.forEach(function(e) { |
+ list.push({host: e, elements: this.elementsInsideShadyRoot(e)}); |
+ }, this); |
+ return list; |
+ }, |
+ |
+ elementsWithShadyRoot: function() { |
+ var e$ = Polymer.dom(document).querySelectorAll('*'); |
+ return this.filterElementsWithRoots(e$); |
+ }, |
+ |
+ elementsInsideShadyRoot: function(e) { |
+ var e$ = Polymer.dom(e.root || e).querySelectorAll('*'); |
+ var roots = this.filterElementsWithRoots(e$); |
+ roots.forEach(function(e) { |
+ e$ = e$.concat(this.elementsInsideShadyRoot(e)); |
+ }, this); |
+ return e$; |
+ }, |
+ |
+ filterElementsWithRoots: function(elements) { |
+ return elements.filter(function(e) { |
+ return e.shadyRoot; |
+ }); |
+ } |
+ |
+ }; |
+ |
+ // dump an auditor report |
+ var logger = { |
+ |
+ dump: function(log) { |
+ log.forEach(function(l) { |
+ console.group(l.sheet.ownerNode); |
+ this.dumpRules(l.rules); |
+ console.groupEnd(l.sheet.ownerNode); |
+ }, this); |
+ }, |
+ |
+ dumpRules: function(rules) { |
+ rules.forEach(function(i) { |
+ console.group(i.selector); |
+ console.log(i.elements); |
+ console.groupEnd(i.selector); |
+ }); |
+ } |
+ |
+ }; |
+ |
+ // pruduces a style audit and reports results on the console. |
+ function audit() { |
+ var report = auditor.matchesForDocument(crawler.list()); |
+ logger.dump(report); |
+ } |
+ |
+ audit(); |
+ |
+}); |
+</script> |