mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Add @polymerMixin and @memberof annotations. Misc doc cleanup.
* `TODOC` indicates docs that need further elaboration/review.
This commit is contained in:
parent
25f5a55346
commit
b9f5b4c271
@ -8,60 +8,6 @@ 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
|
||||
-->
|
||||
|
||||
<!--
|
||||
Keeping structured data in sync requires that Polymer understand the path
|
||||
associations of data being bound. The `array-selector` element ensures path
|
||||
linkage when selecting specific items from an array (either single or multiple).
|
||||
The `items` property accepts an array of user data, and via the `select(item)`
|
||||
and `deselect(item)` API, updates the `selected` property which may be bound to
|
||||
other parts of the application, and any changes to sub-fields of `selected`
|
||||
item(s) will be kept in sync with items in the `items` array. When `multi`
|
||||
is false, `selected` is a property representing the last selected item. When
|
||||
`multi` is true, `selected` is an array of multiply selected items.
|
||||
|
||||
```html
|
||||
<dom-module id="employee-list">
|
||||
|
||||
<template>
|
||||
|
||||
<div> Employee list: </div>
|
||||
<template is="dom-repeat" id="employeeList" items="{{employees}}">
|
||||
<div>First name: <span>{{item.first}}</span></div>
|
||||
<div>Last name: <span>{{item.last}}</span></div>
|
||||
<button on-click="toggleSelection">Select</button>
|
||||
</template>
|
||||
|
||||
<array-selector id="selector" items="{{employees}}" selected="{{selected}}" multi toggle></array-selector>
|
||||
|
||||
<div> Selected employees: </div>
|
||||
<template is="dom-repeat" items="{{selected}}">
|
||||
<div>First name: <span>{{item.first}}</span></div>
|
||||
<div>Last name: <span>{{item.last}}</span></div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'employee-list',
|
||||
ready() {
|
||||
this.employees = [
|
||||
{first: 'Bob', last: 'Smith'},
|
||||
{first: 'Sally', last: 'Johnson'},
|
||||
...
|
||||
];
|
||||
},
|
||||
toggleSelection(e) {
|
||||
var item = this.$.employeeList.itemForElement(e.target);
|
||||
this.$.selector.select(item);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</dom-module>
|
||||
```
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../polymer-element.html">
|
||||
<link rel="import" href="../utils/mixin.html">
|
||||
<link rel="import" href="../utils/array-splice.html">
|
||||
@ -69,6 +15,23 @@ is false, `selected` is a property representing the last selected item. When
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* Element mixin for recording dynamic associations between item paths in a
|
||||
* master `items` array and a `selected` array such that path changes to the
|
||||
* master array (at the host) element or elsewhere via data-binding) are
|
||||
* correctly propagated to items in the selected array and vice-versa.
|
||||
*
|
||||
* The `items` property accepts an array of user data, and via the
|
||||
* `select(item)` and `deselect(item)` API, updates the `selected` property
|
||||
* which may be bound to other parts of the application, and any changes to
|
||||
* sub-fields of `selected` item(s) will be kept in sync with items in the
|
||||
* `items` array. When `multi` is false, `selected` is a property
|
||||
* representing the last selected item. When `multi` is true, `selected`
|
||||
* is an array of multiply selected items.
|
||||
*
|
||||
* @polymerMixin
|
||||
* @memberof Polymer
|
||||
*/
|
||||
let ArraySelectorMixin = Polymer.dedupingMixin(superClass => {
|
||||
|
||||
return class extends superClass {
|
||||
@ -361,9 +324,76 @@ is false, `selected` is a property representing the last selected item. When
|
||||
// export mixin
|
||||
Polymer.ArraySelectorMixin = ArraySelectorMixin;
|
||||
|
||||
// define element class & export
|
||||
const ArraySelector = ArraySelectorMixin(Polymer.Element);
|
||||
customElements.define('array-selector', ArraySelector);
|
||||
/**
|
||||
* Element implementing the `Polymer.ArraySelector` mixin, which records
|
||||
* dynamic associations between item paths in a master `items` array and a
|
||||
* `selected` array such that path changes to the master array (at the host)
|
||||
* element or elsewhere via data-binding) are correctly propagated to items
|
||||
* in the selected array and vice-versa.
|
||||
*
|
||||
* The `items` property accepts an array of user data, and via the
|
||||
* `select(item)` and `deselect(item)` API, updates the `selected` property
|
||||
* which may be bound to other parts of the application, and any changes to
|
||||
* sub-fields of `selected` item(s) will be kept in sync with items in the
|
||||
* `items` array. When `multi` is false, `selected` is a property
|
||||
* representing the last selected item. When `multi` is true, `selected`
|
||||
* is an array of multiply selected items.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```html
|
||||
* <dom-module id="employee-list">
|
||||
*
|
||||
* <template>
|
||||
*
|
||||
* <div> Employee list: </div>
|
||||
* <template is="dom-repeat" id="employeeList" items="{{employees}}">
|
||||
* <div>First name: <span>{{item.first}}</span></div>
|
||||
* <div>Last name: <span>{{item.last}}</span></div>
|
||||
* <button on-click="toggleSelection">Select</button>
|
||||
* </template>
|
||||
*
|
||||
* <array-selector id="selector" items="{{employees}}" selected="{{selected}}" multi toggle></array-selector>
|
||||
*
|
||||
* <div> Selected employees: </div>
|
||||
* <template is="dom-repeat" items="{{selected}}">
|
||||
* <div>First name: <span>{{item.first}}</span></div>
|
||||
* <div>Last name: <span>{{item.last}}</span></div>
|
||||
* </template>
|
||||
*
|
||||
* </template>
|
||||
*
|
||||
* </dom-module>
|
||||
* ```
|
||||
*
|
||||
* ```js
|
||||
* Polymer({
|
||||
* is: 'employee-list',
|
||||
* ready() {
|
||||
* this.employees = [
|
||||
* {first: 'Bob', last: 'Smith'},
|
||||
* {first: 'Sally', last: 'Johnson'},
|
||||
* ...
|
||||
* ];
|
||||
* },
|
||||
* toggleSelection(e) {
|
||||
* var item = this.$.employeeList.itemForElement(e.target);
|
||||
* this.$.selector.select(item);
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @polymerElement
|
||||
* @extends Polymer.Element
|
||||
* @mixes Polymer.ArraySelectorMixin
|
||||
* @memberof Polymer
|
||||
*/
|
||||
const ArraySelector = class extends ArraySelectorMixin(Polymer.Element) {
|
||||
// Not needed to find template; can be removed once the analyzer
|
||||
// can find the tag name from customElements.define call
|
||||
static get is() { return 'array-selector' }
|
||||
}
|
||||
customElements.define(ArraySelector.is, ArraySelector);
|
||||
Polymer.ArraySelector = ArraySelector;
|
||||
|
||||
})();
|
||||
|
@ -17,6 +17,23 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
const CustomStyleInterface = window.ShadyCSS.CustomStyleInterface;
|
||||
|
||||
/**
|
||||
* Custom element for defining styles in the main document that can take
|
||||
* advantage of several special features of Polymer's styling system:
|
||||
*
|
||||
* - Document styles defined in a custom-style are shimmed to ensure they
|
||||
* do not leak into local DOM when running on browsers without native
|
||||
* Shadow DOM.
|
||||
* - Custom properties used by Polymer's shim for cross-scope styling may
|
||||
* be defined in an custom-style. Use the :root selector to define custom
|
||||
* properties that apply to all custom elements.
|
||||
*
|
||||
* To use, simply wrap an inline `<style>` tag in the main document whose
|
||||
* CSS uses these features with a `<custom-style>` element.
|
||||
*
|
||||
* @extends HTMLElement
|
||||
* @memberof Polymer
|
||||
*/
|
||||
class CustomStyle extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
|
@ -15,9 +15,23 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
(function() {
|
||||
|
||||
const mixin = Polymer.PropertyEffects(HTMLElement);
|
||||
const domBindBase = Polymer.PropertyEffects(HTMLElement);
|
||||
|
||||
class DomBind extends mixin {
|
||||
/**
|
||||
* Custom element to allow using Polymer's template features (data binding,
|
||||
* declarative event listeners, etc.) in the main document without defining
|
||||
* a new custom element.
|
||||
*
|
||||
* `<template>` tags utilizing bindings may be wrapped with the `<dom-bind>`
|
||||
* element, which will immediately stamp the wrapped template into the main
|
||||
* document and bind elements to the `dom-bind` element itself as the
|
||||
* binding scope.
|
||||
*
|
||||
* @extends HTMLElement
|
||||
* @mixes Polymer.PropertyEffects
|
||||
* @memberof Polymer
|
||||
*/
|
||||
class DomBind extends domBindBase {
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
|
@ -18,7 +18,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* Stamps the template iff the `if` property is truthy.
|
||||
* The `<dom-if>` element will stamp a light-dom `<template>` child when
|
||||
* the `if` property becomes truthy, and the template can use Polymer
|
||||
* data-binding and declarative event features when used in the context of
|
||||
* a Polymer element's template.
|
||||
*
|
||||
* When `if` becomes falsey, the stamped content is hidden but not
|
||||
* removed from dom. When `if` subsequently becomes truthy again, the content
|
||||
@ -28,9 +31,17 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
*
|
||||
* Set the `restamp` property to true to force the stamped content to be
|
||||
* created / destroyed when the `if` condition changes.
|
||||
*
|
||||
* @polymerElement
|
||||
* @extends Polymer.Element
|
||||
* @memberof Polymer
|
||||
*/
|
||||
class DomIf extends Polymer.Element {
|
||||
|
||||
// Not needed to find template; can be removed once the analyzer
|
||||
// can find the tag name from customElements.define call
|
||||
static get is() { return 'dom-if'; }
|
||||
|
||||
static get template() { return null; }
|
||||
|
||||
static get properties() {
|
||||
@ -237,7 +248,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
}
|
||||
|
||||
customElements.define('dom-if', DomIf);
|
||||
customElements.define(DomIf.is, DomIf);
|
||||
|
||||
Polymer.DomIf = DomIf;
|
||||
|
||||
|
@ -30,6 +30,8 @@
|
||||
*
|
||||
* let img = document.createElement('dom-module').import('foo', 'img');
|
||||
*
|
||||
* @extends HTMLElement
|
||||
* @memberof Polymer
|
||||
*/
|
||||
class DomModule extends HTMLElement {
|
||||
|
||||
|
@ -8,96 +8,6 @@ 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
|
||||
-->
|
||||
|
||||
<!--
|
||||
|
||||
The `dom-repeat` element is a custom `HTMLTemplateElement` type extension that
|
||||
automatically stamps and binds one instance of template content to each object
|
||||
in a user-provided array. `dom-repeat` accepts an `items` property, and one
|
||||
instance of the template is stamped for each item into the DOM at the location
|
||||
of the `dom-repeat` element. The `item` property will be set on each instance's
|
||||
binding scope, thus templates should bind to sub-properties of `item`.
|
||||
|
||||
Example:
|
||||
|
||||
```html
|
||||
<dom-module id="employee-list">
|
||||
|
||||
<template>
|
||||
|
||||
<div> Employee list: </div>
|
||||
<template is="dom-repeat" items="{{employees}}">
|
||||
<div>First name: <span>{{item.first}}</span></div>
|
||||
<div>Last name: <span>{{item.last}}</span></div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'employee-list',
|
||||
ready: function() {
|
||||
this.employees = [
|
||||
{first: 'Bob', last: 'Smith'},
|
||||
{first: 'Sally', last: 'Johnson'},
|
||||
...
|
||||
];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</dom-module>
|
||||
```
|
||||
|
||||
Notifications for changes to items sub-properties will be forwarded to template
|
||||
instances, which will update via the normal structured data notification system.
|
||||
|
||||
Mutations to the `items` array itself should me made using the Array
|
||||
mutation API's on `Polymer.Base` (`push`, `pop`, `splice`, `shift`,
|
||||
`unshift`), and template instances will be kept in sync with the data in the
|
||||
array.
|
||||
|
||||
Events caught by event handlers within the `dom-repeat` template will be
|
||||
decorated with a `model` property, which represents the binding scope for
|
||||
each template instance. The model is an instance of Polymer.Base, and should
|
||||
be used to manipulate data on the instance, for example
|
||||
`event.model.set('item.checked', true);`.
|
||||
|
||||
Alternatively, the model for a template instance for an element stamped by
|
||||
a `dom-repeat` can be obtained using the `modelForElement` API on the
|
||||
`dom-repeat` that stamped it, for example
|
||||
`this.$.domRepeat.modelForElement(event.target).set('item.checked', true);`.
|
||||
This may be useful for manipulating instance data of event targets obtained
|
||||
by event handlers on parents of the `dom-repeat` (event delegation).
|
||||
|
||||
A view-specific filter/sort may be applied to each `dom-repeat` by supplying a
|
||||
`filter` and/or `sort` property. This may be a string that names a function on
|
||||
the host, or a function may be assigned to the property directly. The functions
|
||||
should implemented following the standard `Array` filter/sort API.
|
||||
|
||||
In order to re-run the filter or sort functions based on changes to sub-fields
|
||||
of `items`, the `observe` property may be set as a space-separated list of
|
||||
`item` sub-fields that should cause a re-filter/sort when modified. If
|
||||
the filter or sort function depends on properties not contained in `items`,
|
||||
the user should observe changes to those properties and call `render` to update
|
||||
the view based on the dependency change.
|
||||
|
||||
For example, for an `dom-repeat` with a filter of the following:
|
||||
|
||||
```js
|
||||
isEngineer: function(item) {
|
||||
return item.type == 'engineer' || item.manager.type == 'engineer';
|
||||
}
|
||||
```
|
||||
|
||||
Then the `observe` property should be configured as follows:
|
||||
|
||||
```html
|
||||
<template is="dom-repeat" items="{{employees}}"
|
||||
filter="isEngineer" observe="type manager.type">
|
||||
```
|
||||
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../polymer-element.html">
|
||||
<link rel="import" href="../utils/templatize.html">
|
||||
<link rel="import" href="../utils/debounce.html">
|
||||
@ -107,8 +17,103 @@ Then the `observe` property should be configured as follows:
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* The `<dom-repeat>` element will automatically stamp and binds one instance
|
||||
* of template content to each object in a user-provided array.
|
||||
* `dom-repeat` accepts an `items` property, and one instance of the template
|
||||
* is stamped for each item into the DOM at the location of the `dom-repeat`
|
||||
* element. The `item` property will be set on each instance's binding
|
||||
* scope, thus templates should bind to sub-properties of `item`.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```html
|
||||
* <dom-module id="employee-list">
|
||||
*
|
||||
* <template>
|
||||
*
|
||||
* <div> Employee list: </div>
|
||||
* <template is="dom-repeat" items="{{employees}}">
|
||||
* <div>First name: <span>{{item.first}}</span></div>
|
||||
* <div>Last name: <span>{{item.last}}</span></div>
|
||||
* </template>
|
||||
*
|
||||
* </template>
|
||||
*
|
||||
* <script>
|
||||
* Polymer({
|
||||
* is: 'employee-list',
|
||||
* ready: function() {
|
||||
* this.employees = [
|
||||
* {first: 'Bob', last: 'Smith'},
|
||||
* {first: 'Sally', last: 'Johnson'},
|
||||
* ...
|
||||
* ];
|
||||
* }
|
||||
* });
|
||||
* </script>
|
||||
*
|
||||
* </dom-module>
|
||||
* ```
|
||||
*
|
||||
* Notifications for changes to items sub-properties will be forwarded to template
|
||||
* instances, which will update via the normal structured data notification system.
|
||||
*
|
||||
* Mutations to the `items` array itself should me made using the Array
|
||||
* mutation API's on `Polymer.Base` (`push`, `pop`, `splice`, `shift`,
|
||||
* `unshift`), and template instances will be kept in sync with the data in the
|
||||
* array.
|
||||
*
|
||||
* Events caught by event handlers within the `dom-repeat` template will be
|
||||
* decorated with a `model` property, which represents the binding scope for
|
||||
* each template instance. The model is an instance of Polymer.Base, and should
|
||||
* be used to manipulate data on the instance, for example
|
||||
* `event.model.set('item.checked', true);`.
|
||||
*
|
||||
* Alternatively, the model for a template instance for an element stamped by
|
||||
* a `dom-repeat` can be obtained using the `modelForElement` API on the
|
||||
* `dom-repeat` that stamped it, for example
|
||||
* `this.$.domRepeat.modelForElement(event.target).set('item.checked', true);`.
|
||||
* This may be useful for manipulating instance data of event targets obtained
|
||||
* by event handlers on parents of the `dom-repeat` (event delegation).
|
||||
*
|
||||
* A view-specific filter/sort may be applied to each `dom-repeat` by supplying a
|
||||
* `filter` and/or `sort` property. This may be a string that names a function on
|
||||
* the host, or a function may be assigned to the property directly. The functions
|
||||
* should implemented following the standard `Array` filter/sort API.
|
||||
*
|
||||
* In order to re-run the filter or sort functions based on changes to sub-fields
|
||||
* of `items`, the `observe` property may be set as a space-separated list of
|
||||
* `item` sub-fields that should cause a re-filter/sort when modified. If
|
||||
* the filter or sort function depends on properties not contained in `items`,
|
||||
* the user should observe changes to those properties and call `render` to update
|
||||
* the view based on the dependency change.
|
||||
*
|
||||
* For example, for an `dom-repeat` with a filter of the following:
|
||||
*
|
||||
* ```js
|
||||
* isEngineer: function(item) {
|
||||
* return item.type == 'engineer' || item.manager.type == 'engineer';
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Then the `observe` property should be configured as follows:
|
||||
*
|
||||
* ```html
|
||||
* <template is="dom-repeat" items="{{employees}}"
|
||||
* filter="isEngineer" observe="type manager.type">
|
||||
* ```
|
||||
*
|
||||
* @polymerElement
|
||||
* @extends Polymer.Element
|
||||
* @memberof Polymer
|
||||
*/
|
||||
class DomRepeat extends Polymer.Element {
|
||||
|
||||
// Not needed to find template; can be removed once the analyzer
|
||||
// can find the tag name from customElements.define call
|
||||
static get is() { return 'dom-repeat'; }
|
||||
|
||||
static get template() { return null; }
|
||||
|
||||
static get properties() {
|
||||
@ -661,7 +666,7 @@ Then the `observe` property should be configured as follows:
|
||||
|
||||
}
|
||||
|
||||
customElements.define('dom-repeat', DomRepeat);
|
||||
customElements.define(DomRepeat.is, DomRepeat);
|
||||
|
||||
Polymer.DomRepeat = DomRepeat;
|
||||
|
||||
|
@ -32,6 +32,15 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
listeners: true
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a "legacy" behavior or array of behaviors to the provided class.
|
||||
*
|
||||
* TODOC
|
||||
*
|
||||
* @param {Object|Array} behaviors Behavior object or array of behaviors
|
||||
* @param {HTMLElement} klass Element class
|
||||
* @memberof Polymer
|
||||
*/
|
||||
function mixinBehaviors(behaviors, klass) {
|
||||
if (!behaviors) {
|
||||
return klass;
|
||||
@ -231,6 +240,20 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
return PolymerGenerated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a class that extends `Polymer.LegacyElement` based on the
|
||||
* provided info object. Metadata objects on the `info` object
|
||||
* (`properties`, `observers`, `listeners`, `behaviors`, `is`) are used
|
||||
* for Polymer's meta-programming systems, and any functions are copied
|
||||
* to the generated class.
|
||||
*
|
||||
* TODOC
|
||||
*
|
||||
* @param {Object} info Object containing Polymer metadata and functions
|
||||
* to become class methods.
|
||||
* @return {Polymer.LegacyElement} Generated class
|
||||
* @memberof Polymer
|
||||
*/
|
||||
Polymer.Class = function(info) {
|
||||
if (!info) {
|
||||
Polymer._warn('Polymer.Class requires `info` argument');
|
||||
|
@ -24,9 +24,22 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
let styleInterface = window.ShadyCSS;
|
||||
|
||||
/**
|
||||
* Element class mixin that provides Polymer's "legacy" API intended to be
|
||||
* backward-compatible to the greatest extent possible with the API
|
||||
* found on the Polymer 1.x `Polymer.Base` prototype applied to all elements
|
||||
* defined using the `Polymer({...})` function.
|
||||
*
|
||||
* TODOC
|
||||
*
|
||||
* @polymerMixin
|
||||
* @mixes Polymer.ElementMixin
|
||||
* @mixes Polymer.GestureEventListeners
|
||||
* @memberof Polymer
|
||||
*/
|
||||
Polymer.LegacyElementMixin = Polymer.dedupingMixin(function(base) {
|
||||
|
||||
const mixin = Polymer.GestureEventListeners(Polymer.ElementMixin(base));
|
||||
const legacyElementBase = Polymer.GestureEventListeners(Polymer.ElementMixin(base));
|
||||
|
||||
/**
|
||||
* Map of simple names to touch action names
|
||||
@ -39,7 +52,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
'all': 'auto'
|
||||
};
|
||||
|
||||
return class LegacyElement extends mixin {
|
||||
return class LegacyElement extends legacyElementBase {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
@ -14,6 +14,18 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* Legacy class factory and registration helper for defining Polymer
|
||||
* elements.
|
||||
*
|
||||
* TODOC
|
||||
*
|
||||
* @namespace Polymer
|
||||
* @function Polymer
|
||||
* @param {Object} info Object containing Polymer metadata and functions
|
||||
* to become class methods.
|
||||
* @return {Polymer.LegacyElement} Generated class
|
||||
*/
|
||||
window.Polymer._polymerFn = function(info) {
|
||||
// if input is a `class` (aka a function with a prototype), use the prototype
|
||||
// remember that the `constructor` will never be called
|
||||
|
@ -13,16 +13,25 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
let matchesSelector = (function() {
|
||||
let p = Element.prototype;
|
||||
let normalizedMatchesSelector = p.matches || p.matchesSelector ||
|
||||
p.mozMatchesSelector || p.msMatchesSelector ||
|
||||
p.oMatchesSelector || p.webkitMatchesSelector;
|
||||
const p = Element.prototype;
|
||||
const normalizedMatchesSelector = p.matches || p.matchesSelector ||
|
||||
p.mozMatchesSelector || p.msMatchesSelector ||
|
||||
p.oMatchesSelector || p.webkitMatchesSelector;
|
||||
|
||||
return function(node, selector) {
|
||||
return normalizedMatchesSelector.call(node, selector);
|
||||
}
|
||||
})();
|
||||
/**
|
||||
* Cross-platform `element.matches` shim.
|
||||
*
|
||||
* TODOC
|
||||
*
|
||||
* @function matchesSelector
|
||||
* @memberof Polymer
|
||||
* @param {Node} node Node to check selector against
|
||||
* @param {string} selector Selector to match
|
||||
* @return {boolean} True if node matched selector
|
||||
*/
|
||||
const matchesSelector = function(node, selector) {
|
||||
return normalizedMatchesSelector.call(node, selector);
|
||||
}
|
||||
|
||||
class DomApi {
|
||||
|
||||
@ -174,6 +183,20 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy DOM manipulation API used to abstract differences between native
|
||||
* Shadow DOM and "Shady DOM" when polyfilling on older browsers.
|
||||
*
|
||||
* Note that in Polymer 2.x use of `Polymer.dom` is no longer required and
|
||||
* in the majority of cases simply facades directly to the standard native
|
||||
* API.
|
||||
*
|
||||
* TODOC
|
||||
*
|
||||
* @memberof Polymer
|
||||
* @param {Node|Event} obj Node or event to operate on
|
||||
* @return {DomApi|EventApi} Wrapper providing either node API or event API
|
||||
*/
|
||||
Polymer.dom = function(obj) {
|
||||
obj = obj || document;
|
||||
let ctor = obj instanceof Event ? EventApi : DomApi;
|
||||
|
@ -14,6 +14,68 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* The `Polymer.Templatizer` behavior adds methods to generate instances of
|
||||
* templates that are each managed by an anonymous `Polymer.PropertyEffects`
|
||||
* instance where data-bindings in the stamped template content are bound to
|
||||
* accessors on itself.
|
||||
*
|
||||
* This behavior is provided in Polymer 2.x as a hybrid-element convenience
|
||||
* only. For non-legacy/hybrid usage, the `Polymer.Templatize` library
|
||||
* should be used instead.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* // Get a template from somewhere, e.g. light DOM
|
||||
* var template = this.querySelector('template');
|
||||
* // Prepare the template
|
||||
* this.templatize(template);
|
||||
* // Instance the template with an initial data model
|
||||
* var instance = this.stamp({myProp: 'initial'});
|
||||
* // Insert the instance's DOM somewhere, e.g. light DOM
|
||||
* Polymer.dom(this).appendChild(instance.root);
|
||||
* // Changing a property on the instance will propagate to bindings
|
||||
* // in the template
|
||||
* instance.myProp = 'new value';
|
||||
*
|
||||
* Users of `Templatizer` may need to implement the following abstract
|
||||
* API's to determine how properties and paths from the host should be
|
||||
* forwarded into to instances:
|
||||
*
|
||||
* _forwardHostPropV2: function(prop, value)
|
||||
*
|
||||
* Likewise, users may implement these additional abstract API's to determine
|
||||
* how instance-specific properties that change on the instance should be
|
||||
* forwarded out to the host, if necessary.
|
||||
*
|
||||
* _notifyInstancePropV2: function(inst, prop, value)
|
||||
*
|
||||
* In order to determine which properties are instance-specific and require
|
||||
* custom forwarding via `_forwardInstanceProp`/`_forwardInstancePath`,
|
||||
* define an `_instanceProps` map containing keys for each instance prop,
|
||||
* for example:
|
||||
*
|
||||
* _instanceProps: {
|
||||
* item: true,
|
||||
* index: true
|
||||
* }
|
||||
*
|
||||
* Any properties used in the template that are not defined in _instanceProp
|
||||
* will be forwarded out to the host automatically.
|
||||
*
|
||||
* Users should also implement the following abstract function to show or
|
||||
* hide any DOM generated using `stamp`:
|
||||
*
|
||||
* _showHideChildren: function(shouldHide)
|
||||
*
|
||||
* Note that some callbacks are suffixed with `V2` in the Polymer 2.x behavior
|
||||
* as the implementations will need to differ from the callbacks required
|
||||
* by the 1.x Templatizer API due to changes in the `TemplateInstance` API
|
||||
* between versions 1.x and 2.x.
|
||||
*
|
||||
* @polymerBehavior
|
||||
* @memberof Polymer
|
||||
*/
|
||||
let Templatizer = {
|
||||
templatize(template) {
|
||||
this._templatizerTemplate = template;
|
||||
|
@ -17,9 +17,20 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
<link rel="import" href="property-effects.html">
|
||||
|
||||
<script>
|
||||
/**
|
||||
* Element class mixin that provides the core API for Polymer's meta-programming
|
||||
* features including template stamping, data-binding, attribute deserialization,
|
||||
* and property change observation.
|
||||
*
|
||||
* TODOC
|
||||
*
|
||||
* @polymerMixin
|
||||
* @mixes Polymer.PropertyEffects
|
||||
* @memberof Polymer
|
||||
*/
|
||||
Polymer.ElementMixin = Polymer.dedupingMixin(function(base) {
|
||||
|
||||
const mixin = Polymer.PropertyEffects(base);
|
||||
const polymerElementBase = Polymer.PropertyEffects(base);
|
||||
|
||||
let caseMap = Polymer.CaseMap;
|
||||
|
||||
@ -321,9 +332,10 @@ Polymer.ElementMixin = Polymer.dedupingMixin(function(base) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @polymerMixinClass
|
||||
* @unrestricted
|
||||
*/
|
||||
class PolymerElement extends mixin {
|
||||
class PolymerElement extends polymerElementBase {
|
||||
|
||||
static get observedAttributes() {
|
||||
if (!this.hasOwnProperty(goog.reflect.objectProperty('__observedAttributes', this))) {
|
||||
|
@ -17,6 +17,18 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
const gestures = Polymer.Gestures;
|
||||
|
||||
/**
|
||||
* Element class mixin that provides API for adding Polymer's cross-platform
|
||||
* gesture events to nodes.
|
||||
*
|
||||
* The API is designed to be compatible with override points implemented
|
||||
* in `Polymer.TemplateStamp` such that declarative event listeners in
|
||||
* templates will support gesture events when this mixin is applied along with
|
||||
* `Polymer.TemplateStamp`.
|
||||
*
|
||||
* @polymerMixin
|
||||
* @memberof Polymer
|
||||
*/
|
||||
Polymer.GestureEventListeners = Polymer.dedupingMixin(function(superClass) {
|
||||
|
||||
return class GestureEventListeners extends superClass {
|
||||
|
@ -70,6 +70,22 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* TODOC
|
||||
*
|
||||
* @polymerMixin
|
||||
* @memberof Polymer
|
||||
*/
|
||||
Polymer.PropertyAccessors = Polymer.dedupingMixin(function(superClass) {
|
||||
|
||||
return class PropertyAccessors extends superClass {
|
||||
|
@ -1203,11 +1203,23 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Element class mixin that provides meta-programming for Polymer's template
|
||||
* binding and data observation (collectively, "property effects") system.
|
||||
*
|
||||
* TODOC
|
||||
*
|
||||
* @polymerMixin
|
||||
* @mixes Polymer.TemplateStamp
|
||||
* @mixes Polymer.PropertyAccessors
|
||||
* @memberof Polymer
|
||||
*/
|
||||
Polymer.PropertyEffects = Polymer.dedupingMixin(function(superClass) {
|
||||
|
||||
const mixin = Polymer.TemplateStamp(Polymer.PropertyAccessors(superClass));
|
||||
|
||||
/**
|
||||
* @polymerMixinClass
|
||||
* @unrestricted
|
||||
*/
|
||||
class PropertyEffects extends mixin {
|
||||
|
@ -16,99 +16,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Scans a template to produce an annotation object that stores expression
|
||||
* metadata along with information to associate the metadata with nodes in an
|
||||
* instance.
|
||||
*
|
||||
* Elements with `id` in the template are noted and marshaled into an
|
||||
* the `$` hash in an instance.
|
||||
*
|
||||
* Example
|
||||
*
|
||||
* <template>
|
||||
* <div id="foo"></div>
|
||||
* </template>
|
||||
* <script>
|
||||
* Polymer({
|
||||
* task: function() {
|
||||
* this.$.foo.style.color = 'red';
|
||||
* }
|
||||
* });
|
||||
* </script>
|
||||
*
|
||||
* Other expressions that are noted include:
|
||||
*
|
||||
* Double-mustache annotations in text content. The annotation must be the only
|
||||
* content in the tag, compound expressions are not (currently) supported.
|
||||
*
|
||||
* <[tag]>{{path.to.host.property}}<[tag]>
|
||||
*
|
||||
* Double-mustache annotations in an attribute.
|
||||
*
|
||||
* <[tag] someAttribute="{{path.to.host.property}}"><[tag]>
|
||||
*
|
||||
* Only immediate host properties can automatically trigger side-effects.
|
||||
* Setting `host.path` in the example above triggers the binding, setting
|
||||
* `host.path.to.host.property` does not.
|
||||
*
|
||||
* `on-` style event declarations.
|
||||
*
|
||||
* <[tag] on-<event-name>="{{hostMethodName}}"><[tag]>
|
||||
*
|
||||
* Note: **the `annotations` feature does not actually implement the behaviors
|
||||
* associated with these expressions, it only captures the data**.
|
||||
*
|
||||
* Other optional features contain actual data implementations.
|
||||
*
|
||||
* @class standard feature: annotations
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Scans a template to produce an annotation map that stores expression metadata
|
||||
and information that associates the metadata to nodes in a template instance.
|
||||
|
||||
Supported annotations are:
|
||||
|
||||
* id attributes
|
||||
* binding annotations in text nodes
|
||||
* double-mustache expressions: {{expression}}
|
||||
* double-bracket expressions: [[expression]]
|
||||
* binding annotations in attributes
|
||||
* attribute-bind expressions: name="{{expression}} || [[expression]]"
|
||||
* property-bind expressions: name*="{{expression}} || [[expression]]"
|
||||
* property-bind expressions: name:="expression"
|
||||
* event annotations
|
||||
* event delegation directives: on-<eventName>="expression"
|
||||
|
||||
Generated data-structure:
|
||||
|
||||
[
|
||||
{
|
||||
id: '<id>',
|
||||
events: [
|
||||
{
|
||||
mode: ['auto'|''],
|
||||
name: '<name>'
|
||||
value: '<expression>'
|
||||
}, ...
|
||||
],
|
||||
bindings: [
|
||||
{
|
||||
kind: ['text'|'attribute'|'property'],
|
||||
mode: ['auto'|''],
|
||||
name: '<name>'
|
||||
value: '<expression>'
|
||||
}, ...
|
||||
],
|
||||
parent: <reference to parent annotation>,
|
||||
index: <integer index in parent's childNodes collection>
|
||||
},
|
||||
...
|
||||
]
|
||||
*/
|
||||
|
||||
// null-array (shared empty array to avoid null-checks)
|
||||
const emptyArray = [];
|
||||
|
||||
@ -134,6 +41,46 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
let insertionPointTag = 'slot';
|
||||
|
||||
/**
|
||||
* Scans a template to produce an annotation map that stores expression metadata
|
||||
* and information that associates the metadata to nodes in a template instance.
|
||||
*
|
||||
* Supported annotations are:
|
||||
* * id attributes
|
||||
* * binding annotations in text nodes
|
||||
* * double-mustache expressions: {{expression}}
|
||||
* * double-bracket expressions: [[expression]]
|
||||
* * binding annotations in attributes
|
||||
* * attribute-bind expressions: name="{{expression}} || [[expression]]"
|
||||
* * property-bind expressions: name*="{{expression}} || [[expression]]"
|
||||
* * property-bind expressions: name:="expression"
|
||||
* * event annotations
|
||||
* * event delegation directives: on-<eventName>="expression"
|
||||
*
|
||||
* Generated data-structure:
|
||||
* [
|
||||
* {
|
||||
* id: '<id>',
|
||||
* events: [
|
||||
* {
|
||||
* mode: ['auto'|''],
|
||||
* name: '<name>'
|
||||
* value: '<expression>'
|
||||
* }, ...
|
||||
* ],
|
||||
* bindings: [
|
||||
* {
|
||||
* kind: ['text'|'attribute'|'property'],
|
||||
* mode: ['auto'|''],
|
||||
* name: '<name>'
|
||||
* value: '<expression>'
|
||||
* }, ...
|
||||
* ],
|
||||
* parent: <reference to parent annotation>,
|
||||
* index: <integer index in parent's childNodes collection>
|
||||
* },
|
||||
* ...
|
||||
* ]
|
||||
*
|
||||
* @param {HTMLTemplateElement} template
|
||||
* @param {boolean=} stripWhiteSpace
|
||||
* @return {Array<Object>}
|
||||
@ -487,6 +434,22 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Element mixin that provides basic template parsing and stamping, including
|
||||
* the following template-related features for stamped templates:
|
||||
*
|
||||
* - Declarative event listeners (`on-eventname="listener"`)
|
||||
* - Map of node id's to stamped node instances (`this.$.id`)
|
||||
* - Nested template content caching/removal and re-installation (performance
|
||||
* optimization)
|
||||
* - Relative URL's relative to original template location
|
||||
* - Template binding annotation parsing (note that this library only parses
|
||||
* template bindings and provides annotation metadata; see
|
||||
* `Polymer.PropertyEffects` for a full implementation of data-binding)
|
||||
*
|
||||
* @polymerMixin
|
||||
* @memberof Polymer
|
||||
*/
|
||||
Polymer.TemplateStamp = Polymer.dedupingMixin(function(superClass) {
|
||||
|
||||
return class TemplateStamp extends superClass {
|
||||
@ -507,7 +470,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||
* event listeners (`on-...``), `id`'s, `<template>`s, and bindings
|
||||
* (`{{...}}` and `[[...]]`). This template metadata ("notes")
|
||||
* are stored as `this._templateNotes`, and any nodes identified in
|
||||
* with notes are collected for this instance into `_templateNodes` in
|
||||
* notes are collected for this instance into `_templateNodes` in
|
||||
* the same order as the notes array.
|
||||
*
|
||||
* Finally, this method generates an "id map" for all nodes with id's
|
||||
|
Loading…
Reference in New Issue
Block a user