Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Unified Diff: appengine/config_service/ui/bower_components/shadycss/src/scoping-shim.js

Issue 2923973003: Added base template for config ui. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: appengine/config_service/ui/bower_components/shadycss/src/scoping-shim.js
diff --git a/appengine/config_service/ui/bower_components/shadycss/src/scoping-shim.js b/appengine/config_service/ui/bower_components/shadycss/src/scoping-shim.js
new file mode 100644
index 0000000000000000000000000000000000000000..87813051e71ebe99e78da3c4e4f4127a71370764
--- /dev/null
+++ b/appengine/config_service/ui/bower_components/shadycss/src/scoping-shim.js
@@ -0,0 +1,481 @@
+/**
+@license
+Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+*/
+
+'use strict';
+
+import {parse, StyleNode} from './css-parse.js'
+import {nativeShadow, nativeCssVariables} from './style-settings.js'
+import StyleTransformer from './style-transformer.js'
+import * as StyleUtil from './style-util.js'
+import StyleProperties from './style-properties.js'
+import placeholderMap from './style-placeholder.js'
+import StyleInfo from './style-info.js'
+import StyleCache from './style-cache.js'
+import {flush as watcherFlush} from './document-watcher.js'
+import templateMap from './template-map.js'
+import * as ApplyShimUtils from './apply-shim-utils.js'
+import documentWait from './document-wait.js'
+import {updateNativeProperties, detectMixin} from './common-utils.js'
+import {CustomStyleInterfaceInterface} from './custom-style-interface.js' //eslint-disable-line no-unused-vars
+
+/**
+ * @const {StyleCache}
+ */
+const styleCache = new StyleCache();
+
+export default class ScopingShim {
+ constructor() {
+ this._scopeCounter = {};
+ this._documentOwner = document.documentElement;
+ let ast = new StyleNode();
+ ast['rules'] = [];
+ this._documentOwnerStyleInfo = StyleInfo.set(this._documentOwner, new StyleInfo(ast));
+ this._elementsHaveApplied = false;
+ this._applyShim = null;
+ /** @type {?CustomStyleInterfaceInterface} */
+ this._customStyleInterface = null;
+ documentWait(() => {
+ this._ensure();
+ });
+ }
+ flush() {
+ watcherFlush();
+ }
+ _generateScopeSelector(name) {
+ let id = this._scopeCounter[name] = (this._scopeCounter[name] || 0) + 1;
+ return `${name}-${id}`;
+ }
+ getStyleAst(style) {
+ return StyleUtil.rulesForStyle(style);
+ }
+ styleAstToString(ast) {
+ return StyleUtil.toCssText(ast);
+ }
+ _gatherStyles(template) {
+ let styles = template.content.querySelectorAll('style');
+ let cssText = [];
+ for (let i = 0; i < styles.length; i++) {
+ let s = styles[i];
+ cssText.push(s.textContent);
+ s.parentNode.removeChild(s);
+ }
+ return cssText.join('').trim();
+ }
+ _getCssBuild(template) {
+ let style = template.content.querySelector('style');
+ if (!style) {
+ return '';
+ }
+ return style.getAttribute('css-build') || '';
+ }
+ /**
+ * Prepare the styling and template for the given element type
+ *
+ * @param {HTMLTemplateElement} template
+ * @param {string} elementName
+ * @param {string=} typeExtension
+ */
+ prepareTemplate(template, elementName, typeExtension) {
+ if (template._prepared) {
+ return;
+ }
+ template._prepared = true;
+ template.name = elementName;
+ template.extends = typeExtension;
+ templateMap[elementName] = template;
+ let cssBuild = this._getCssBuild(template);
+ let cssText = this._gatherStyles(template);
+ let info = {
+ is: elementName,
+ extends: typeExtension,
+ __cssBuild: cssBuild,
+ };
+ if (!nativeShadow) {
+ StyleTransformer.dom(template.content, elementName);
+ }
+ // check if the styling has mixin definitions or uses
+ this._ensure();
+ let hasMixins = detectMixin(cssText)
+ let ast = parse(cssText);
+ // only run the applyshim transforms if there is a mixin involved
+ if (hasMixins && nativeCssVariables && this._applyShim) {
+ this._applyShim['transformRules'](ast, elementName);
+ }
+ template['_styleAst'] = ast;
+ template._cssBuild = cssBuild;
+
+ let ownPropertyNames = [];
+ if (!nativeCssVariables) {
+ ownPropertyNames = StyleProperties.decorateStyles(template['_styleAst'], info);
+ }
+ if (!ownPropertyNames.length || nativeCssVariables) {
+ let root = nativeShadow ? template.content : null;
+ let placeholder = placeholderMap[elementName];
+ let style = this._generateStaticStyle(info, template['_styleAst'], root, placeholder);
+ template._style = style;
+ }
+ template._ownPropertyNames = ownPropertyNames;
+ }
+ _generateStaticStyle(info, rules, shadowroot, placeholder) {
+ let cssText = StyleTransformer.elementStyles(info, rules);
+ if (cssText.length) {
+ return StyleUtil.applyCss(cssText, info.is, shadowroot, placeholder);
+ }
+ }
+ _prepareHost(host) {
+ let {is, typeExtension} = StyleUtil.getIsExtends(host);
+ let placeholder = placeholderMap[is];
+ let template = templateMap[is];
+ let ast;
+ let ownStylePropertyNames;
+ let cssBuild;
+ if (template) {
+ ast = template['_styleAst'];
+ ownStylePropertyNames = template._ownPropertyNames;
+ cssBuild = template._cssBuild;
+ }
+ return StyleInfo.set(host,
+ new StyleInfo(
+ ast,
+ placeholder,
+ ownStylePropertyNames,
+ is,
+ typeExtension,
+ cssBuild
+ )
+ );
+ }
+ _ensureApplyShim() {
+ if (this._applyShim) {
+ return;
+ } else if (window.ShadyCSS && window.ShadyCSS.ApplyShim) {
+ this._applyShim = window.ShadyCSS.ApplyShim;
+ this._applyShim['invalidCallback'] = ApplyShimUtils.invalidate;
+ }
+ }
+ _ensureCustomStyleInterface() {
+ if (this._customStyleInterface) {
+ return;
+ } else if (window.ShadyCSS && window.ShadyCSS.CustomStyleInterface) {
+ this._customStyleInterface = /** @type {!CustomStyleInterfaceInterface} */(window.ShadyCSS.CustomStyleInterface);
+ /** @type {function(!HTMLStyleElement)} */
+ this._customStyleInterface['transformCallback'] = (style) => {this.transformCustomStyleForDocument(style)};
+ this._customStyleInterface['validateCallback'] = () => {
+ requestAnimationFrame(() => {
+ if (this._customStyleInterface['enqueued'] || this._elementsHaveApplied) {
+ this.flushCustomStyles();
+ }
+ })
+ };
+ }
+ }
+ _ensure() {
+ this._ensureApplyShim();
+ this._ensureCustomStyleInterface();
+ }
+ /**
+ * Flush and apply custom styles to document
+ */
+ flushCustomStyles() {
+ this._ensure();
+ if (!this._customStyleInterface) {
+ return;
+ }
+ let customStyles = this._customStyleInterface['processStyles']();
+ // early return if custom-styles don't need validation
+ if (!this._customStyleInterface['enqueued']) {
+ return;
+ }
+ if (!nativeCssVariables) {
+ this._updateProperties(this._documentOwner, this._documentOwnerStyleInfo);
+ this._applyCustomStyles(customStyles);
+ } else {
+ this._revalidateCustomStyleApplyShim(customStyles);
+ }
+ this._customStyleInterface['enqueued'] = false;
+ // if custom elements have upgraded and there are no native css variables, we must recalculate the whole tree
+ if (this._elementsHaveApplied && !nativeCssVariables) {
+ this.styleDocument();
+ }
+ }
+ /**
+ * Apply styles for the given element
+ *
+ * @param {!HTMLElement} host
+ * @param {Object=} overrideProps
+ */
+ styleElement(host, overrideProps) {
+ let {is} = StyleUtil.getIsExtends(host);
+ let styleInfo = StyleInfo.get(host);
+ if (!styleInfo) {
+ styleInfo = this._prepareHost(host);
+ }
+ // Only trip the `elementsHaveApplied` flag if a node other that the root document has `applyStyle` called
+ if (!this._isRootOwner(host)) {
+ this._elementsHaveApplied = true;
+ }
+ if (overrideProps) {
+ styleInfo.overrideStyleProperties =
+ styleInfo.overrideStyleProperties || {};
+ Object.assign(styleInfo.overrideStyleProperties, overrideProps);
+ }
+ if (!nativeCssVariables) {
+ this._updateProperties(host, styleInfo);
+ if (styleInfo.ownStylePropertyNames && styleInfo.ownStylePropertyNames.length) {
+ this._applyStyleProperties(host, styleInfo);
+ }
+ } else {
+ if (styleInfo.overrideStyleProperties) {
+ updateNativeProperties(host, styleInfo.overrideStyleProperties);
+ }
+ let template = templateMap[is];
+ // bail early if there is no shadowroot for this element
+ if (!template && !this._isRootOwner(host)) {
+ return;
+ }
+ if (template && template._style && !ApplyShimUtils.templateIsValid(template)) {
+ // update template
+ if (!ApplyShimUtils.templateIsValidating(template)) {
+ this._ensure();
+ this._applyShim && this._applyShim['transformRules'](template['_styleAst'], is);
+ template._style.textContent = StyleTransformer.elementStyles(host, styleInfo.styleRules);
+ ApplyShimUtils.startValidatingTemplate(template);
+ }
+ // update instance if native shadowdom
+ if (nativeShadow) {
+ let root = host.shadowRoot;
+ if (root) {
+ let style = root.querySelector('style');
+ style.textContent = StyleTransformer.elementStyles(host, styleInfo.styleRules);
+ }
+ }
+ styleInfo.styleRules = template['_styleAst'];
+ }
+ }
+ }
+ _styleOwnerForNode(node) {
+ let root = node.getRootNode();
+ let host = root.host;
+ if (host) {
+ if (StyleInfo.get(host)) {
+ return host;
+ } else {
+ return this._styleOwnerForNode(host);
+ }
+ }
+ return this._documentOwner;
+ }
+ _isRootOwner(node) {
+ return (node === this._documentOwner);
+ }
+ _applyStyleProperties(host, styleInfo) {
+ let is = StyleUtil.getIsExtends(host).is;
+ let cacheEntry = styleCache.fetch(is, styleInfo.styleProperties, styleInfo.ownStylePropertyNames);
+ let cachedScopeSelector = cacheEntry && cacheEntry.scopeSelector;
+ let cachedStyle = cacheEntry ? cacheEntry.styleElement : null;
+ let oldScopeSelector = styleInfo.scopeSelector;
+ // only generate new scope if cached style is not found
+ styleInfo.scopeSelector = cachedScopeSelector || this._generateScopeSelector(is);
+ let style = StyleProperties.applyElementStyle(host, styleInfo.styleProperties, styleInfo.scopeSelector, cachedStyle);
+ if (!nativeShadow) {
+ StyleProperties.applyElementScopeSelector(host, styleInfo.scopeSelector, oldScopeSelector);
+ }
+ if (!cacheEntry) {
+ styleCache.store(is, styleInfo.styleProperties, style, styleInfo.scopeSelector);
+ }
+ return style;
+ }
+ _updateProperties(host, styleInfo) {
+ let owner = this._styleOwnerForNode(host);
+ let ownerStyleInfo = StyleInfo.get(owner);
+ let ownerProperties = ownerStyleInfo.styleProperties;
+ let props = Object.create(ownerProperties || null);
+ let hostAndRootProps = StyleProperties.hostAndRootPropertiesForScope(host, styleInfo.styleRules);
+ let propertyData = StyleProperties.propertyDataFromStyles(ownerStyleInfo.styleRules, host);
+ let propertiesMatchingHost = propertyData.properties
+ Object.assign(
+ props,
+ hostAndRootProps.hostProps,
+ propertiesMatchingHost,
+ hostAndRootProps.rootProps
+ );
+ this._mixinOverrideStyles(props, styleInfo.overrideStyleProperties);
+ StyleProperties.reify(props);
+ styleInfo.styleProperties = props;
+ }
+ _mixinOverrideStyles(props, overrides) {
+ for (let p in overrides) {
+ let v = overrides[p];
+ // skip override props if they are not truthy or 0
+ // in order to fall back to inherited values
+ if (v || v === 0) {
+ props[p] = v;
+ }
+ }
+ }
+ /**
+ * Update styles of the whole document
+ *
+ * @param {Object=} properties
+ */
+ styleDocument(properties) {
+ this.styleSubtree(this._documentOwner, properties);
+ }
+ /**
+ * Update styles of a subtree
+ *
+ * @param {!HTMLElement} host
+ * @param {Object=} properties
+ */
+ styleSubtree(host, properties) {
+ let root = host.shadowRoot;
+ if (root || this._isRootOwner(host)) {
+ this.styleElement(host, properties);
+ }
+ // process the shadowdom children of `host`
+ let shadowChildren = root && (root.children || root.childNodes);
+ if (shadowChildren) {
+ for (let i = 0; i < shadowChildren.length; i++) {
+ let c = /** @type {!HTMLElement} */(shadowChildren[i]);
+ this.styleSubtree(c);
+ }
+ } else {
+ // process the lightdom children of `host`
+ let children = host.children || host.childNodes;
+ if (children) {
+ for (let i = 0; i < children.length; i++) {
+ let c = /** @type {!HTMLElement} */(children[i]);
+ this.styleSubtree(c);
+ }
+ }
+ }
+ }
+ /* Custom Style operations */
+ _revalidateCustomStyleApplyShim(customStyles) {
+ for (let i = 0; i < customStyles.length; i++) {
+ let c = customStyles[i];
+ let s = this._customStyleInterface['getStyleForCustomStyle'](c);
+ if (s) {
+ this._revalidateApplyShim(s);
+ }
+ }
+ }
+ _applyCustomStyles(customStyles) {
+ for (let i = 0; i < customStyles.length; i++) {
+ let c = customStyles[i];
+ let s = this._customStyleInterface['getStyleForCustomStyle'](c);
+ if (s) {
+ StyleProperties.applyCustomStyle(s, this._documentOwnerStyleInfo.styleProperties);
+ }
+ }
+ }
+ transformCustomStyleForDocument(style) {
+ let ast = StyleUtil.rulesForStyle(style);
+ StyleUtil.forEachRule(ast, (rule) => {
+ if (nativeShadow) {
+ StyleTransformer.normalizeRootSelector(rule);
+ } else {
+ StyleTransformer.documentRule(rule);
+ }
+ if (nativeCssVariables) {
+ this._ensure();
+ this._applyShim && this._applyShim['transformRule'](rule);
+ }
+ });
+ if (nativeCssVariables) {
+ style.textContent = StyleUtil.toCssText(ast);
+ } else {
+ this._documentOwnerStyleInfo.styleRules.rules.push(ast);
+ }
+ }
+ _revalidateApplyShim(style) {
+ if (nativeCssVariables && this._applyShim) {
+ let ast = StyleUtil.rulesForStyle(style);
+ this._ensure();
+ this._applyShim['transformRules'](ast);
+ style.textContent = StyleUtil.toCssText(ast);
+ }
+ }
+ getComputedStyleValue(element, property) {
+ let value;
+ if (!nativeCssVariables) {
+ // element is either a style host, or an ancestor of a style host
+ let styleInfo = StyleInfo.get(element) || StyleInfo.get(this._styleOwnerForNode(element));
+ value = styleInfo.styleProperties[property];
+ }
+ // fall back to the property value from the computed styling
+ value = value || window.getComputedStyle(element).getPropertyValue(property);
+ // trim whitespace that can come after the `:` in css
+ // example: padding: 2px -> " 2px"
+ return value ? value.trim() : '';
+ }
+ // given an element and a classString, replaces
+ // the element's class with the provided classString and adds
+ // any necessary ShadyCSS static and property based scoping selectors
+ setElementClass(element, classString) {
+ let root = element.getRootNode();
+ let classes = classString ? classString.split(/\s/) : [];
+ let scopeName = root.host && root.host.localName;
+ // If no scope, try to discover scope name from existing class.
+ // This can occur if, for example, a template stamped element that
+ // has been scoped is manipulated when not in a root.
+ if (!scopeName) {
+ var classAttr = element.getAttribute('class');
+ if (classAttr) {
+ let k$ = classAttr.split(/\s/);
+ for (let i=0; i < k$.length; i++) {
+ if (k$[i] === StyleTransformer.SCOPE_NAME) {
+ scopeName = k$[i+1];
+ break;
+ }
+ }
+ }
+ }
+ if (scopeName) {
+ classes.push(StyleTransformer.SCOPE_NAME, scopeName);
+ }
+ if (!nativeCssVariables) {
+ let styleInfo = StyleInfo.get(element);
+ if (styleInfo && styleInfo.scopeSelector) {
+ classes.push(StyleProperties.XSCOPE_NAME, styleInfo.scopeSelector);
+ }
+ }
+ StyleUtil.setElementClassRaw(element, classes.join(' '));
+ }
+ _styleInfoForNode(node) {
+ return StyleInfo.get(node);
+ }
+}
+
+/* exports */
+ScopingShim.prototype['flush'] = ScopingShim.prototype.flush;
+ScopingShim.prototype['prepareTemplate'] = ScopingShim.prototype.prepareTemplate;
+ScopingShim.prototype['styleElement'] = ScopingShim.prototype.styleElement;
+ScopingShim.prototype['styleDocument'] = ScopingShim.prototype.styleDocument;
+ScopingShim.prototype['styleSubtree'] = ScopingShim.prototype.styleSubtree;
+ScopingShim.prototype['getComputedStyleValue'] = ScopingShim.prototype.getComputedStyleValue;
+ScopingShim.prototype['setElementClass'] = ScopingShim.prototype.setElementClass;
+ScopingShim.prototype['_styleInfoForNode'] = ScopingShim.prototype._styleInfoForNode;
+ScopingShim.prototype['transformCustomStyleForDocument'] = ScopingShim.prototype.transformCustomStyleForDocument;
+ScopingShim.prototype['getStyleAst'] = ScopingShim.prototype.getStyleAst;
+ScopingShim.prototype['styleAstToString'] = ScopingShim.prototype.styleAstToString;
+ScopingShim.prototype['flushCustomStyles'] = ScopingShim.prototype.flushCustomStyles;
+Object.defineProperties(ScopingShim.prototype, {
+ 'nativeShadow': {
+ get() {
+ return nativeShadow;
+ }
+ },
+ 'nativeCss': {
+ get() {
+ return nativeCssVariables;
+ }
+ }
+});

Powered by Google App Engine
This is Rietveld 408576698