diff options
Diffstat (limited to 'catapult/third_party/polymer/components/shadycss/src/apply-shim-utils.js')
-rw-r--r-- | catapult/third_party/polymer/components/shadycss/src/apply-shim-utils.js | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/catapult/third_party/polymer/components/shadycss/src/apply-shim-utils.js b/catapult/third_party/polymer/components/shadycss/src/apply-shim-utils.js new file mode 100644 index 00000000..c5c27a2b --- /dev/null +++ b/catapult/third_party/polymer/components/shadycss/src/apply-shim-utils.js @@ -0,0 +1,149 @@ +/** +@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 templateMap from './template-map.js'; +import {StyleNode} from './css-parse.js'; // eslint-disable-line no-unused-vars + +/* + * Utilities for handling invalidating apply-shim mixins for a given template. + * + * The invalidation strategy involves keeping track of the "current" version of a template's mixins, and updating that count when a mixin is invalidated. + * The template + */ + +/** @const {string} */ +const CURRENT_VERSION = '_applyShimCurrentVersion'; + +/** @const {string} */ +const NEXT_VERSION = '_applyShimNextVersion'; + +/** @const {string} */ +const VALIDATING_VERSION = '_applyShimValidatingVersion'; + +/** + * @const {Promise<void>} + */ +const promise = Promise.resolve(); + +/** + * @param {string} elementName + */ +export function invalidate(elementName){ + let template = templateMap[elementName]; + if (template) { + invalidateTemplate(template); + } +} + +/** + * This function can be called multiple times to mark a template invalid + * and signal that the style inside must be regenerated. + * + * Use `startValidatingTemplate` to begin an asynchronous validation cycle. + * During that cycle, call `templateIsValidating` to see if the template must + * be revalidated + * @param {HTMLTemplateElement} template + */ +export function invalidateTemplate(template) { + // default the current version to 0 + template[CURRENT_VERSION] = template[CURRENT_VERSION] || 0; + // ensure the "validating for" flag exists + template[VALIDATING_VERSION] = template[VALIDATING_VERSION] || 0; + // increment the next version + template[NEXT_VERSION] = (template[NEXT_VERSION] || 0) + 1; +} + +/** + * @param {string} elementName + * @return {boolean} + */ +export function isValid(elementName) { + let template = templateMap[elementName]; + if (template) { + return templateIsValid(template); + } + return true; +} + +/** + * @param {HTMLTemplateElement} template + * @return {boolean} + */ +export function templateIsValid(template) { + return template[CURRENT_VERSION] === template[NEXT_VERSION]; +} + +/** + * @param {string} elementName + * @return {boolean} + */ +export function isValidating(elementName) { + let template = templateMap[elementName]; + if (template) { + return templateIsValidating(template); + } + return false; +} + +/** + * Returns true if the template is currently invalid and `startValidating` has been called since the last invalidation. + * If false, the template must be validated. + * @param {HTMLTemplateElement} template + * @return {boolean} + */ +export function templateIsValidating(template) { + return !templateIsValid(template) && template[VALIDATING_VERSION] === template[NEXT_VERSION]; +} + +/** + * the template is marked as `validating` for one microtask so that all instances + * found in the tree crawl of `applyStyle` will update themselves, + * but the template will only be updated once. + * @param {string} elementName +*/ +export function startValidating(elementName) { + let template = templateMap[elementName]; + startValidatingTemplate(template); +} + +/** + * Begin an asynchronous invalidation cycle. + * This should be called after every validation of a template + * + * After one microtask, the template will be marked as valid until the next call to `invalidateTemplate` + * @param {HTMLTemplateElement} template + */ +export function startValidatingTemplate(template) { + // remember that the current "next version" is the reason for this validation cycle + template[VALIDATING_VERSION] = template[NEXT_VERSION]; + // however, there only needs to be one async task to clear the counters + if (!template._validating) { + template._validating = true; + promise.then(function() { + // sync the current version to let future invalidations cause a refresh cycle + template[CURRENT_VERSION] = template[NEXT_VERSION]; + template._validating = false; + }); + } +} + +/** + * @return {boolean} + */ +export function elementsAreInvalid() { + for (let elementName in templateMap) { + let template = templateMap[elementName]; + if (!templateIsValid(template)) { + return true; + } + } + return false; +} |