summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/catapult/third_party/polymer3/bower_components/polymer/lib/mixins/dir-mixin.js
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/catapult/third_party/polymer3/bower_components/polymer/lib/mixins/dir-mixin.js')
-rw-r--r--chromium/third_party/catapult/third_party/polymer3/bower_components/polymer/lib/mixins/dir-mixin.js179
1 files changed, 179 insertions, 0 deletions
diff --git a/chromium/third_party/catapult/third_party/polymer3/bower_components/polymer/lib/mixins/dir-mixin.js b/chromium/third_party/catapult/third_party/polymer3/bower_components/polymer/lib/mixins/dir-mixin.js
new file mode 100644
index 00000000000..0e6d31e34fe
--- /dev/null
+++ b/chromium/third_party/catapult/third_party/polymer3/bower_components/polymer/lib/mixins/dir-mixin.js
@@ -0,0 +1,179 @@
+/**
+@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
+*/
+import { PropertyAccessors } from './property-accessors.js';
+
+import { dedupingMixin } from '../utils/mixin.js';
+
+const HOST_DIR = /:host\(:dir\((ltr|rtl)\)\)/g;
+const HOST_DIR_REPLACMENT = ':host([dir="$1"])';
+
+const EL_DIR = /([\s\w-#\.\[\]\*]*):dir\((ltr|rtl)\)/g;
+const EL_DIR_REPLACMENT = ':host([dir="$2"]) $1';
+
+/**
+ * @type {!Array<!Polymer_DirMixin>}
+ */
+const DIR_INSTANCES = [];
+
+/** @type {MutationObserver} */
+let observer = null;
+
+let DOCUMENT_DIR = '';
+
+function getRTL() {
+ DOCUMENT_DIR = document.documentElement.getAttribute('dir');
+}
+
+/**
+ * @param {!Polymer_DirMixin} instance Instance to set RTL status on
+ */
+function setRTL(instance) {
+ if (!instance.__autoDirOptOut) {
+ const el = /** @type {!HTMLElement} */(instance);
+ el.setAttribute('dir', DOCUMENT_DIR);
+ }
+}
+
+function updateDirection() {
+ getRTL();
+ DOCUMENT_DIR = document.documentElement.getAttribute('dir');
+ for (let i = 0; i < DIR_INSTANCES.length; i++) {
+ setRTL(DIR_INSTANCES[i]);
+ }
+}
+
+function takeRecords() {
+ if (observer && observer.takeRecords().length) {
+ updateDirection();
+ }
+}
+
+/**
+ * Element class mixin that allows elements to use the `:dir` CSS Selector to
+ * have text direction specific styling.
+ *
+ * With this mixin, any stylesheet provided in the template will transform
+ * `:dir` into `:host([dir])` and sync direction with the page via the
+ * element's `dir` attribute.
+ *
+ * Elements can opt out of the global page text direction by setting the `dir`
+ * attribute directly in `ready()` or in HTML.
+ *
+ * Caveats:
+ * - Applications must set `<html dir="ltr">` or `<html dir="rtl">` to sync
+ * direction
+ * - Automatic left-to-right or right-to-left styling is sync'd with the
+ * `<html>` element only.
+ * - Changing `dir` at runtime is supported.
+ * - Opting out of the global direction styling is permanent
+ *
+ * @mixinFunction
+ * @polymer
+ * @appliesMixin PropertyAccessors
+ */
+export const DirMixin = dedupingMixin((base) => {
+
+ if (!observer) {
+ getRTL();
+ observer = new MutationObserver(updateDirection);
+ observer.observe(document.documentElement, {attributes: true, attributeFilter: ['dir']});
+ }
+
+ /**
+ * @constructor
+ * @extends {base}
+ * @implements {Polymer_PropertyAccessors}
+ */
+ const elementBase = PropertyAccessors(base);
+
+ /**
+ * @polymer
+ * @mixinClass
+ * @implements {Polymer_DirMixin}
+ */
+ class Dir extends elementBase {
+
+ /**
+ * @override
+ * @suppress {missingProperties} Interfaces in closure do not inherit statics, but classes do
+ */
+ static _processStyleText(cssText, baseURI) {
+ cssText = super._processStyleText(cssText, baseURI);
+ cssText = this._replaceDirInCssText(cssText);
+ return cssText;
+ }
+
+ /**
+ * Replace `:dir` in the given CSS text
+ *
+ * @param {string} text CSS text to replace DIR
+ * @return {string} Modified CSS
+ */
+ static _replaceDirInCssText(text) {
+ let replacedText = text;
+ replacedText = replacedText.replace(HOST_DIR, HOST_DIR_REPLACMENT);
+ replacedText = replacedText.replace(EL_DIR, EL_DIR_REPLACMENT);
+ if (text !== replacedText) {
+ this.__activateDir = true;
+ }
+ return replacedText;
+ }
+
+ constructor() {
+ super();
+ /** @type {boolean} */
+ this.__autoDirOptOut = false;
+ }
+
+ /**
+ * @suppress {invalidCasts} Closure doesn't understand that `this` is an HTMLElement
+ * @return {void}
+ */
+ ready() {
+ super.ready();
+ this.__autoDirOptOut = /** @type {!HTMLElement} */(this).hasAttribute('dir');
+ }
+
+ /**
+ * @suppress {missingProperties} If it exists on elementBase, it can be super'd
+ * @return {void}
+ */
+ connectedCallback() {
+ if (elementBase.prototype.connectedCallback) {
+ super.connectedCallback();
+ }
+ if (this.constructor.__activateDir) {
+ takeRecords();
+ DIR_INSTANCES.push(this);
+ setRTL(this);
+ }
+ }
+
+ /**
+ * @suppress {missingProperties} If it exists on elementBase, it can be super'd
+ * @return {void}
+ */
+ disconnectedCallback() {
+ if (elementBase.prototype.disconnectedCallback) {
+ super.disconnectedCallback();
+ }
+ if (this.constructor.__activateDir) {
+ const idx = DIR_INSTANCES.indexOf(this);
+ if (idx > -1) {
+ DIR_INSTANCES.splice(idx, 1);
+ }
+ }
+ }
+ }
+
+ Dir.__activateDir = false;
+
+ return Dir;
+});