Index: third_party/polymer/components-chromium/core-style/core-style-extracted.js |
diff --git a/third_party/polymer/components-chromium/core-style/core-style-extracted.js b/third_party/polymer/components-chromium/core-style/core-style-extracted.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4bad9d70d2f3d22d2c1e33efcb6f7bb738cfaba7 |
--- /dev/null |
+++ b/third_party/polymer/components-chromium/core-style/core-style-extracted.js |
@@ -0,0 +1,284 @@ |
+ |
+(function() { |
+ |
+window.CoreStyle = window.CoreStyle || { |
+ g: {}, |
+ list: {}, |
+ refMap: {} |
+}; |
+ |
+Polymer('core-style', { |
+ /** |
+ * The `id` property should be set if the `core-style` is a producer |
+ * of styles. In this case, the `core-style` should have text content |
+ * that is cssText. |
+ * |
+ * @attribute id |
+ * @type string |
+ * @default '' |
+ */ |
+ |
+ |
+ publish: { |
+ /** |
+ * The `ref` property should be set if the `core-style` element is a |
+ * consumer of styles. Set it to the `id` of the desired `core-style` |
+ * element. |
+ * |
+ * @attribute ref |
+ * @type string |
+ * @default '' |
+ */ |
+ ref: '' |
+ }, |
+ |
+ // static |
+ g: CoreStyle.g, |
+ refMap: CoreStyle.refMap, |
+ |
+ /** |
+ * The `list` is a map of all `core-style` producers stored by `id`. It |
+ * should be considered readonly. It's useful for nesting one `core-style` |
+ * inside another. |
+ * |
+ * @attribute list |
+ * @type object (readonly) |
+ * @default {map of all `core-style` producers} |
+ */ |
+ list: CoreStyle.list, |
+ |
+ // if we have an id, we provide style |
+ // if we have a ref, we consume/require style |
+ ready: function() { |
+ if (this.id) { |
+ this.provide(); |
+ } else { |
+ this.registerRef(this.ref); |
+ if (!window.ShadowDOMPolyfill) { |
+ this.require(); |
+ } |
+ } |
+ }, |
+ |
+ // can't shim until attached if using SD polyfill because need to find host |
+ attached: function() { |
+ if (!this.id && window.ShadowDOMPolyfill) { |
+ this.require(); |
+ } |
+ }, |
+ |
+ /****** producer stuff *******/ |
+ |
+ provide: function() { |
+ this.register(); |
+ // we want to do this asap, especially so we can do so before definitions |
+ // that use this core-style are registered. |
+ if (this.textContent) { |
+ this._completeProvide(); |
+ } else { |
+ this.async(this._completeProvide); |
+ } |
+ }, |
+ |
+ register: function() { |
+ var i = this.list[this.id]; |
+ if (i) { |
+ if (!Array.isArray(i)) { |
+ this.list[this.id] = [i]; |
+ } |
+ this.list[this.id].push(this); |
+ } else { |
+ this.list[this.id] = this; |
+ } |
+ }, |
+ |
+ // stamp into a shadowRoot so we can monitor dom of the bound output |
+ _completeProvide: function() { |
+ this.createShadowRoot(); |
+ this.domObserver = new MutationObserver(this.domModified.bind(this)) |
+ .observe(this.shadowRoot, {subtree: true, |
+ characterData: true, childList: true}); |
+ this.provideContent(); |
+ }, |
+ |
+ provideContent: function() { |
+ this.ensureTemplate(); |
+ this.shadowRoot.textContent = ''; |
+ this.shadowRoot.appendChild(this.instanceTemplate(this.template)); |
+ this.cssText = this.shadowRoot.textContent; |
+ }, |
+ |
+ ensureTemplate: function() { |
+ if (!this.template) { |
+ this.template = this.querySelector('template:not([repeat]):not([bind])'); |
+ // move content into the template |
+ if (!this.template) { |
+ this.template = document.createElement('template'); |
+ var n = this.firstChild; |
+ while (n) { |
+ this.template.content.appendChild(n.cloneNode(true)); |
+ n = n.nextSibling; |
+ } |
+ } |
+ } |
+ }, |
+ |
+ domModified: function() { |
+ this.cssText = this.shadowRoot.textContent; |
+ this.notify(); |
+ }, |
+ |
+ // notify instances that reference this element |
+ notify: function() { |
+ var s$ = this.refMap[this.id]; |
+ if (s$) { |
+ for (var i=0, s; (s=s$[i]); i++) { |
+ s.require(); |
+ } |
+ } |
+ }, |
+ |
+ /****** consumer stuff *******/ |
+ |
+ registerRef: function(ref) { |
+ //console.log('register', ref); |
+ this.refMap[this.ref] = this.refMap[this.ref] || []; |
+ this.refMap[this.ref].push(this); |
+ }, |
+ |
+ applyRef: function(ref) { |
+ this.ref = ref; |
+ this.registerRef(this.ref); |
+ this.require(); |
+ }, |
+ |
+ require: function() { |
+ var cssText = this.cssTextForRef(this.ref); |
+ //console.log('require', this.ref, cssText); |
+ if (cssText) { |
+ this.ensureStyleElement(); |
+ // do nothing if cssText has not changed |
+ if (this.styleElement._cssText === cssText) { |
+ return; |
+ } |
+ this.styleElement._cssText = cssText; |
+ if (window.ShadowDOMPolyfill) { |
+ this.styleElement.textContent = cssText; |
+ cssText = Platform.ShadowCSS.shimStyle(this.styleElement, |
+ this.getScopeSelector()); |
+ } |
+ this.styleElement.textContent = cssText; |
+ } |
+ }, |
+ |
+ cssTextForRef: function(ref) { |
+ var s$ = this.byId(ref); |
+ var cssText = ''; |
+ if (s$) { |
+ if (Array.isArray(s$)) { |
+ var p = []; |
+ for (var i=0, l=s$.length, s; (i<l) && (s=s$[i]); i++) { |
+ p.push(s.cssText); |
+ } |
+ cssText = p.join('\n\n'); |
+ } else { |
+ cssText = s$.cssText; |
+ } |
+ } |
+ if (s$ && !cssText) { |
+ console.warn('No styles provided for ref:', ref); |
+ } |
+ return cssText; |
+ }, |
+ |
+ byId: function(id) { |
+ return this.list[id]; |
+ }, |
+ |
+ ensureStyleElement: function() { |
+ if (!this.styleElement) { |
+ this.styleElement = window.ShadowDOMPolyfill ? |
+ this.makeShimStyle() : |
+ this.makeRootStyle(); |
+ } |
+ if (!this.styleElement) { |
+ console.warn(this.localName, 'could not setup style.'); |
+ } |
+ }, |
+ |
+ makeRootStyle: function() { |
+ var style = document.createElement('style'); |
+ this.appendChild(style); |
+ return style; |
+ }, |
+ |
+ makeShimStyle: function() { |
+ var host = this.findHost(this); |
+ if (host) { |
+ var name = host.localName; |
+ var style = document.querySelector('style[' + name + '=' + this.ref +']'); |
+ if (!style) { |
+ style = document.createElement('style'); |
+ style.setAttribute(name, this.ref); |
+ document.head.appendChild(style); |
+ } |
+ return style; |
+ } |
+ }, |
+ |
+ getScopeSelector: function() { |
+ if (!this._scopeSelector) { |
+ var selector = '', host = this.findHost(this); |
+ if (host) { |
+ var typeExtension = host.hasAttribute('is'); |
+ var name = typeExtension ? host.getAttribute('is') : host.localName; |
+ selector = Platform.ShadowCSS.makeScopeSelector(name, |
+ typeExtension); |
+ } |
+ this._scopeSelector = selector; |
+ } |
+ return this._scopeSelector; |
+ }, |
+ |
+ findHost: function(node) { |
+ while (node.parentNode) { |
+ node = node.parentNode; |
+ } |
+ return node.host || wrap(document.documentElement); |
+ }, |
+ |
+ /* filters! */ |
+ // TODO(dfreedm): add more filters! |
+ |
+ cycle: function(rgb, amount) { |
+ if (rgb.match('#')) { |
+ var o = this.hexToRgb(rgb); |
+ if (!o) { |
+ return rgb; |
+ } |
+ rgb = 'rgb(' + o.r + ',' + o.b + ',' + o.g + ')'; |
+ } |
+ |
+ function cycleChannel(v) { |
+ return Math.abs((Number(v) - amount) % 255); |
+ } |
+ |
+ return rgb.replace(/rgb\(([^,]*),([^,]*),([^,]*)\)/, function(m, a, b, c) { |
+ return 'rgb(' + cycleChannel(a) + ',' + cycleChannel(b) + ', ' |
+ + cycleChannel(c) + ')'; |
+ }); |
+ }, |
+ |
+ hexToRgb: function(hex) { |
+ var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); |
+ return result ? { |
+ r: parseInt(result[1], 16), |
+ g: parseInt(result[2], 16), |
+ b: parseInt(result[3], 16) |
+ } : null; |
+ } |
+ |
+}); |
+ |
+ |
+})(); |