aboutsummaryrefslogtreecommitdiff
path: root/catapult/third_party/polymer/components/shadycss/src/apply-shim-utils.js
diff options
context:
space:
mode:
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.js149
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;
+}