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

Unified Diff: appengine/config_service/ui/bower_components/polymer/lib/mixins/property-accessors.html

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/polymer/lib/mixins/property-accessors.html
diff --git a/appengine/config_service/ui/bower_components/polymer/lib/mixins/property-accessors.html b/appengine/config_service/ui/bower_components/polymer/lib/mixins/property-accessors.html
new file mode 100644
index 0000000000000000000000000000000000000000..3500266aef7709dd5d4f3565979be55e81e93ae3
--- /dev/null
+++ b/appengine/config_service/ui/bower_components/polymer/lib/mixins/property-accessors.html
@@ -0,0 +1,586 @@
+<!--
+@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
+-->
+
+<link rel="import" href="../utils/boot.html">
+<link rel="import" href="../utils/mixin.html">
+<link rel="import" href="../utils/case-map.html">
+<link rel="import" href="../utils/async.html">
+
+<script>
+(function() {
+
+ 'use strict';
+
+ let caseMap = Polymer.CaseMap;
+
+ let microtask = Polymer.Async.microTask;
+
+ // Save map of native properties; this forms a blacklist or properties
+ // that won't have their values "saved" by `saveAccessorValue`, since
+ // reading from an HTMLElement accessor from the context of a prototype throws
+ const nativeProperties = {};
+ let proto = HTMLElement.prototype;
+ while (proto) {
+ let props = Object.getOwnPropertyNames(proto);
+ for (let i=0; i<props.length; i++) {
+ nativeProperties[props[i]] = true;
+ }
+ proto = Object.getPrototypeOf(proto);
+ }
+
+ /**
+ * Used to save the value of a property that will be overridden with
+ * an accessor. If the `model` is a prototype, the values will be saved
+ * in `__dataProto`, and it's up to the user (or downstream mixin) to
+ * decide how/when to set these values back into the accessors.
+ * If `model` is already an instance (it has a `__data` property), then
+ * the value will be set as a pending property, meaning the user should
+ * call `_invalidateProperties` or `_flushProperties` to take effect
+ *
+ * @param {Object} model Prototype or instance
+ * @param {string} property Name of property
+ * @private
+ */
+ function saveAccessorValue(model, property) {
+ // Don't read/store value for any native properties since they could throw
+ if (!nativeProperties[property]) {
+ let value = model[property];
+ if (value !== undefined) {
+ if (model.__data) {
+ // Adding accessor to instance; update the property
+ // It is the user's responsibility to call _flushProperties
+ model._setPendingProperty(property, value);
+ } else {
+ // Adding accessor to proto; save proto's value for instance-time use
+ if (!model.__dataProto) {
+ model.__dataProto = {};
+ } else if (!model.hasOwnProperty(JSCompiler_renameProperty('__dataProto', model))) {
+ model.__dataProto = Object.create(model.__dataProto);
+ }
+ model.__dataProto[property] = value;
+ }
+ }
+ }
+ }
+
+ /**
+ * Element class mixin that provides basic meta-programming for creating one
+ * or more property accessors (getter/setter pair) that enqueue an async
+ * (batched) `_propertiesChanged` callback.
+ *
+ * For basic usage of this mixin, simply declare attributes to observe via
+ * the standard `static get observedAttributes()`, implement `_propertiesChanged`
+ * on the class, and then call `MyClass.createPropertiesForAttributes()` once
+ * on the class to generate property accessors for each observed attribute
+ * prior to instancing. Last, call `this._flushProperties()` once to enable
+ * the accessors.
+ *
+ * Any `observedAttributes` will automatically be
+ * deserialized via `attributeChangedCallback` and set to the associated
+ * property using `dash-case`-to-`camelCase` convention.
+ *
+ * @polymerMixin
+ * @memberof Polymer
+ * @summary Element class mixin for reacting to property changes from
+ * generated property accessors.
+ */
+ Polymer.PropertyAccessors = Polymer.dedupingMixin(superClass => {
+
+ /**
+ * @polymerMixinClass
+ * @implements {Polymer_PropertyAccessors}
+ * @unrestricted
+ */
+ class PropertyAccessors extends superClass {
+
+ /**
+ * Generates property accessors for all attributes in the standard
+ * static `observedAttributes` array.
+ *
+ * Attribute names are mapped to property names using the `dash-case` to
+ * `camelCase` convention
+ *
+ */
+ static createPropertiesForAttributes() {
+ let a$ = this.observedAttributes;
+ for (let i=0; i < a$.length; i++) {
+ this.prototype._createPropertyAccessor(caseMap.dashToCamelCase(a$[i]));
+ }
+ }
+
+ constructor() {
+ super();
+ this._initializeProperties();
+ }
+
+ attributeChangedCallback(name, old, value) {
+ if (old !== value) {
+ this._attributeToProperty(name, value);
+ }
+ }
+
+ /**
+ * Initializes the local storage for property accessors.
+ *
+ * Provided as an override point for performing any setup work prior
+ * to initializing the property accessor system.
+ *
+ * @protected
+ */
+ _initializeProperties() {
+ this.__serializing = false;
+ this.__dataCounter = 0;
+ this.__dataEnabled = false;
+ this.__dataReady = false;
+ this.__dataInvalid = false;
+ // initialize data with prototype values saved when creating accessors
+ this.__data = {};
+ this.__dataPending = null;
+ this.__dataOld = null;
+ if (this.__dataProto) {
+ this._initializeProtoProperties(this.__dataProto);
+ this.__dataProto = null;
+ }
+ // Capture instance properties; these will be set into accessors
+ // during first flush. Don't set them here, since we want
+ // these to overwrite defaults/constructor assignments
+ for (let p in this.__dataHasAccessor) {
+ if (this.hasOwnProperty(p)) {
+ this.__dataInstanceProps = this.__dataInstanceProps || {};
+ this.__dataInstanceProps[p] = this[p];
+ delete this[p];
+ }
+ }
+ }
+
+ /**
+ * Called at instance time with bag of properties that were overwritten
+ * by accessors on the prototype when accessors were created.
+ *
+ * The default implementation sets these properties back into the
+ * setter at instance time. This method is provided as an override
+ * point for customizing or providing more efficient initialization.
+ *
+ * @param {Object} props Bag of property values that were overwritten
+ * when creating property accessors.
+ * @protected
+ */
+ _initializeProtoProperties(props) {
+ for (let p in props) {
+ this._setProperty(p, props[p]);
+ }
+ }
+
+ /**
+ * Called at ready time with bag of instance properties that overwrote
+ * accessors when the element upgraded.
+ *
+ * The default implementation sets these properties back into the
+ * setter at ready time. This method is provided as an override
+ * point for customizing or providing more efficient initialization.
+ *
+ * @param {Object} props Bag of property values that were overwritten
+ * when creating property accessors.
+ * @protected
+ */
+ _initializeInstanceProperties(props) {
+ Object.assign(this, props);
+ }
+
+ /**
+ * Ensures the element has the given attribute. If it does not,
+ * assigns the given value to the attribute.
+ *
+ *
+ * @param {string} attribute Name of attribute to ensure is set.
+ * @param {string} value of the attribute.
+ */
+ _ensureAttribute(attribute, value) {
+ if (!this.hasAttribute(attribute)) {
+ this._valueToNodeAttribute(this, value, attribute);
+ }
+ }
+
+ /**
+ * Deserializes an attribute to its associated property.
+ *
+ * This method calls the `_deserializeValue` method to convert the string to
+ * a typed value.
+ *
+ * @param {string} attribute Name of attribute to deserialize.
+ * @param {string} value of the attribute.
+ * @param {*} type type to deserialize to.
+ */
+ _attributeToProperty(attribute, value, type) {
+ // Don't deserialize back to property if currently reflecting
+ if (!this.__serializing) {
+ let property = caseMap.dashToCamelCase(attribute);
+ this[property] = this._deserializeValue(value, type);
+ }
+ }
+
+ /**
+ * Serializes a property to its associated attribute.
+ *
+ * @param {string} property Property name to reflect.
+ * @param {string=} attribute Attribute name to reflect.
+ * @param {*=} value Property value to refect.
+ */
+ _propertyToAttribute(property, attribute, value) {
+ this.__serializing = true;
+ value = (arguments.length < 3) ? this[property] : value;
+ this._valueToNodeAttribute(this, value,
+ attribute || caseMap.camelToDashCase(property));
+ this.__serializing = false;
+ }
+
+ /**
+ * Sets a typed value to an HTML attribute on a node.
+ *
+ * This method calls the `_serializeValue` method to convert the typed
+ * value to a string. If the `_serializeValue` method returns `undefined`,
+ * the attribute will be removed (this is the default for boolean
+ * type `false`).
+ *
+ * @param {Element} node Element to set attribute to.
+ * @param {*} value Value to serialize.
+ * @param {string} attribute Attribute name to serialize to.
+ */
+ _valueToNodeAttribute(node, value, attribute) {
+ let str = this._serializeValue(value);
+ if (str === undefined) {
+ node.removeAttribute(attribute);
+ } else {
+ node.setAttribute(attribute, str);
+ }
+ }
+
+ /**
+ * Converts a typed JavaScript value to a string.
+ *
+ * This method is called by Polymer when setting JS property values to
+ * HTML attributes. Users may override this method on Polymer element
+ * prototypes to provide serialization for custom types.
+ *
+ * @param {*} value Property value to serialize.
+ * @return {string | undefined} String serialized from the provided property value.
+ */
+ _serializeValue(value) {
+ /* eslint-disable no-fallthrough */
+ switch (typeof value) {
+ case 'boolean':
+ return value ? '' : undefined;
+
+ case 'object':
+ if (value instanceof Date) {
+ return value.toString();
+ } else if (value) {
+ try {
+ return JSON.stringify(value);
+ } catch(x) {
+ return '';
+ }
+ }
+
+ default:
+ return value != null ? value.toString() : undefined;
+ }
+ }
+
+ /**
+ * Converts a string to a typed JavaScript value.
+ *
+ * This method is called by Polymer when reading HTML attribute values to
+ * JS properties. Users may override this method on Polymer element
+ * prototypes to provide deserialization for custom `type`s. Note,
+ * the `type` argument is the value of the `type` field provided in the
+ * `properties` configuration object for a given property, and is
+ * by convention the constructor for the type to deserialize.
+ *
+ * Note: The return value of `undefined` is used as a sentinel value to
+ * indicate the attribute should be removed.
+ *
+ * @param {string} value Attribute value to deserialize.
+ * @param {*} type Type to deserialize the string to.
+ * @return {*} Typed value deserialized from the provided string.
+ */
+ _deserializeValue(value, type) {
+ /**
+ * @type {*}
+ */
+ let outValue;
+ switch (type) {
+ case Number:
+ outValue = Number(value);
+ break;
+
+ case Boolean:
+ outValue = (value !== null);
+ break;
+
+ case Object:
+ try {
+ outValue = JSON.parse(value);
+ } catch(x) {
+ // allow non-JSON literals like Strings and Numbers
+ }
+ break;
+
+ case Array:
+ try {
+ outValue = JSON.parse(value);
+ } catch(x) {
+ outValue = null;
+ console.warn(`Polymer::Attributes: couldn't decode Array as JSON: ${value}`);
+ }
+ break;
+
+ case Date:
+ outValue = new Date(value);
+ break;
+
+ case String:
+ default:
+ outValue = value;
+ break;
+ }
+
+ return outValue;
+ }
+ /* eslint-enable no-fallthrough */
+
+ /**
+ * Creates a setter/getter pair for the named property with its own
+ * local storage. The getter returns the value in the local storage,
+ * and the setter calls `_setProperty`, which updates the local storage
+ * for the property and enqueues a `_propertiesChanged` callback.
+ *
+ * This method may be called on a prototype or an instance. Calling
+ * this method may overwrite a property value that already exists on
+ * the prototype/instance by creating the accessor. When calling on
+ * a prototype, any overwritten values are saved in `__dataProto`,
+ * and it is up to the subclasser to decide how/when to set those
+ * properties back into the accessor. When calling on an instance,
+ * the overwritten value is set via `_setPendingProperty`, and the
+ * user should call `_invalidateProperties` or `_flushProperties`
+ * for the values to take effect.
+ *
+ * @param {string} property Name of the property
+ * @param {boolean=} readOnly When true, no setter is created; the
+ * protected `_setProperty` function must be used to set the property
+ * @protected
+ */
+ _createPropertyAccessor(property, readOnly) {
+ if (!this.hasOwnProperty('__dataHasAccessor')) {
+ this.__dataHasAccessor = Object.assign({}, this.__dataHasAccessor);
+ }
+ if (!this.__dataHasAccessor[property]) {
+ this.__dataHasAccessor[property] = true;
+ saveAccessorValue(this, property);
+ Object.defineProperty(this, property, {
+ get: function() {
+ return this.__data[property];
+ },
+ set: readOnly ? function() { } : function(value) {
+ this._setProperty(property, value);
+ }
+ });
+ }
+ }
+
+ /**
+ * Returns true if this library created an accessor for the given property.
+ *
+ * @param {string} property Property name
+ * @return {boolean} True if an accessor was created
+ */
+ _hasAccessor(property) {
+ return this.__dataHasAccessor && this.__dataHasAccessor[property];
+ }
+
+ /**
+ * Updates the local storage for a property (via `_setPendingProperty`)
+ * and enqueues a `_proeprtiesChanged` callback.
+ *
+ * @param {string} property Name of the property
+ * @param {*} value Value to set
+ * @protected
+ */
+ _setProperty(property, value) {
+ if (this._setPendingProperty(property, value)) {
+ this._invalidateProperties();
+ }
+ }
+
+ /**
+ * Updates the local storage for a property, records the previous value,
+ * and adds it to the set of "pending changes" that will be passed to the
+ * `_propertiesChanged` callback. This method does not enqueue the
+ * `_propertiesChanged` callback.
+ *
+ * @param {string} property Name of the property
+ * @param {*} value Value to set
+ * @return {boolean} Returns true if the property changed
+ * @protected
+ */
+ _setPendingProperty(property, value) {
+ let old = this.__data[property];
+ if (this._shouldPropertyChange(property, value, old)) {
+ if (!this.__dataPending) {
+ this.__dataPending = {};
+ this.__dataOld = {};
+ }
+ // Ensure old is captured from the last turn
+ if (!(property in this.__dataOld)) {
+ this.__dataOld[property] = old;
+ }
+ this.__data[property] = value;
+ this.__dataPending[property] = value;
+ return true;
+ }
+ }
+
+ /**
+ * Returns true if the specified property has a pending change.
+ *
+ * @param {string} prop Property name
+ * @return {boolean} True if property has a pending change
+ * @protected
+ */
+ _isPropertyPending(prop) {
+ return this.__dataPending && (prop in this.__dataPending);
+ }
+
+ /**
+ * Marks the properties as invalid, and enqueues an async
+ * `_propertiesChanged` callback.
+ *
+ * @protected
+ */
+ _invalidateProperties() {
+ if (!this.__dataInvalid && this.__dataReady) {
+ this.__dataInvalid = true;
+ microtask.run(() => {
+ if (this.__dataInvalid) {
+ this.__dataInvalid = false;
+ this._flushProperties();
+ }
+ });
+ }
+ }
+
+ /**
+ * Call to enable property accessor processing. Before this method is
+ * called accessor values will be set but side effects are
+ * queued. When called, any pending side effects occur immediately.
+ * For elements, generally `connectedCallback` is a normal spot to do so.
+ * It is safe to call this method multiple times as it only turns on
+ * property accessors once.
+ */
+ _enableProperties() {
+ if (!this.__dataEnabled) {
+ this.__dataEnabled = true;
+ if (this.__dataInstanceProps) {
+ this._initializeInstanceProperties(this.__dataInstanceProps);
+ this.__dataInstanceProps = null;
+ }
+ this.ready()
+ }
+ }
+
+ /**
+ * Calls the `_propertiesChanged` callback with the current set of
+ * pending changes (and old values recorded when pending changes were
+ * set), and resets the pending set of changes. Generally, this method
+ * should not be called in user code.
+ *
+ *
+ * @protected
+ */
+ _flushProperties() {
+ if (this.__dataPending) {
+ let changedProps = this.__dataPending;
+ this.__dataPending = null;
+ this.__dataCounter++;
+ this._propertiesChanged(this.__data, changedProps, this.__dataOld);
+ this.__dataCounter--;
+ }
+ }
+
+ /**
+ * Lifecycle callback called the first time properties are being flushed.
+ * Prior to `ready`, all property sets through accessors are queued and
+ * their effects are flushed after this method returns.
+ *
+ * Users may override this function to implement behavior that is
+ * dependent on the element having its properties initialized, e.g.
+ * from defaults (initialized from `constructor`, `_initializeProperties`),
+ * `attributeChangedCallback`, or values propagated from host e.g. via
+ * bindings. `super.ready()` must be called to ensure the data system
+ * becomes enabled.
+ *
+ * @public
+ */
+ ready() {
+ this.__dataReady = true;
+ // Run normal flush
+ this._flushProperties();
+ }
+
+ /**
+ * Callback called when any properties with accessors created via
+ * `_createPropertyAccessor` have been set.
+ *
+ * @param {Object} currentProps Bag of all current accessor values
+ * @param {Object} changedProps Bag of properties changed since the last
+ * call to `_propertiesChanged`
+ * @param {Object} oldProps Bag of previous values for each property
+ * in `changedProps`
+ * @protected
+ */
+ _propertiesChanged(currentProps, changedProps, oldProps) { // eslint-disable-line no-unused-vars
+ }
+
+ /**
+ * Method called to determine whether a property value should be
+ * considered as a change and cause the `_propertiesChanged` callback
+ * to be enqueued.
+ *
+ * The default implementation returns `true` for primitive types if a
+ * strict equality check fails, and returns `true` for all Object/Arrays.
+ * The method always returns false for `NaN`.
+ *
+ * Override this method to e.g. provide stricter checking for
+ * Objects/Arrays when using immutable patterns.
+ *
+ * @param {string} property Property name
+ * @param {*} value New property value
+ * @param {*} old Previous property value
+ * @return {boolean} Whether the property should be considered a change
+ * and enqueue a `_proeprtiesChanged` callback
+ * @protected
+ */
+ _shouldPropertyChange(property, value, old) {
+ return (
+ // Strict equality check
+ (old !== value &&
+ // This ensures (old==NaN, value==NaN) always returns false
+ (old === old || value === value))
+ );
+ }
+
+ }
+
+ return PropertyAccessors;
+
+ });
+
+})();
+</script>

Powered by Google App Engine
This is Rietveld 408576698