Skip to content

Commit

Permalink
Update docs. Add warnings.
Browse files Browse the repository at this point in the history
Fixes #1538.  Fixes #1206.
  • Loading branch information
kevinpschaaf committed May 25, 2015
1 parent edb5e95 commit ec83143
Show file tree
Hide file tree
Showing 20 changed files with 455 additions and 66 deletions.
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<script src="../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../iron-doc-viewer/iron-doc-viewer.html">
<link rel="import" href="../iron-component-page/iron-component-page.html">

</head>
<body>

<iron-doc-viewer src="polymer.html"></iron-doc-viewer>
<iron-component-page></iron-component-page>

</body>
</html>
2 changes: 1 addition & 1 deletion src/lib/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

// reserved for canonical behavior
attributeChangedCallback: function(name) {
this.setAttributeToProperty(this, name); // abstract
this._setAttributeToProperty(this, name); // abstract
this._doBehavior('attributeChanged', arguments); // abstract
},

Expand Down
28 changes: 23 additions & 5 deletions src/lib/bind/effects.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,38 @@
},

_observerEffect: function(source, value, effect, old) {
this[effect.method](value, old);
var fn = this[effect.method];
if (fn) {
fn.call(this, value, old);
} else {
this._warn(this._logf('_observerEffect', 'observer method `' +
effect.method + '` not defined'));
}
},

_complexObserverEffect: function(source, value, effect) {
var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
if (args) {
this[effect.method].apply(this, args);
var fn = this[effect.method];
if (fn) {
var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
if (args) {
fn.apply(this, args);
}
} else {
this._warn(this._logf('_complexObserverEffect', 'observer method `' +
effect.method + '` not defined'));
}
},

_computeEffect: function(source, value, effect) {
var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
if (args) {
this[effect.property] = this[effect.method].apply(this, args);
var fn = this[effect.method];
if (fn) {
this[effect.property] = fn.apply(this, args);
} else {
this._warn(this._logf('_computeEffect', 'compute method `' +
effect.method + '` not defined'));
}
}
},

Expand Down
3 changes: 3 additions & 0 deletions src/lib/collection.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
Polymer._collections = new WeakMap();

Polymer.Collection = function(userArray) {
if (!Array.isArray(userArray)) {
host._warn(host._logf('Collection', 'expected array, found [%o]', userArray));
}
Polymer._collections.set(userArray, this);
this.userArray = userArray;
this.store = userArray.slice();
Expand Down
54 changes: 52 additions & 2 deletions src/micro/attributes.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@

_takeAttributesToModel: function(model) {
for (var i=0, l=this.attributes.length; i<l; i++) {
this.setAttributeToProperty(model, this.attributes[i].name);
this._setAttributeToProperty(model, this.attributes[i].name);
}
},

setAttributeToProperty: function(model, attrName) {
_setAttributeToProperty: function(model, attrName) {
// Don't deserialize back to property if currently reflecting
if (!this._serializing) {
var propName = Polymer.CaseMap.dashToCamelCase(attrName);
Expand All @@ -111,20 +111,59 @@

_serializing: false,

/**
* Serializes a property to its associated attribute.
*
* Generally users should set `reflectToAttribute: true` in the
* `properties` configuration to achieve automatic attribute reflection.
*
* @method reflectPropertyToAttribute
* @param {string} name Property name to reflect.
*/
reflectPropertyToAttribute: function(name) {
this._serializing = true;
this.serializeValueToAttribute(this[name],
Polymer.CaseMap.camelToDashCase(name));
this._serializing = false;
},

/**
* Sets a typed value to an HTML attribute on a node.
*
* This method calls the `serialize` method to convert the typed
* value to a string. If the `serialize` method returns `undefined`,
* the attribute will be removed (this is the default for boolean
* type `false`).
*
* @method serializeValueToAttribute
* @param {*} value Value to serialize.
* @param {string} attribute Attribute name to serialize to
*/
serializeValueToAttribute: function(value, attribute, node) {
var str = this.serialize(value);
(node || this)
[str === undefined ? 'removeAttribute' : 'setAttribute']
(attribute, str);
},

/**
* Converts a string to a typed 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.
*
* @method deserialize
* @param {string} value Attribute value to deserialize.
* @param {*} type Type to deserialize the string to.
* @return {*} Typed value deserialized from the provided string.
*/
deserialize: function(value, type) {
switch (type) {
case Number:
Expand Down Expand Up @@ -163,6 +202,17 @@
return value;
},

/**
* Converts a typed 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.
*
* @method serialize
* @param {*} value Property value to serialize.
* @return {string} String serialized from the provided property value.
*/
serialize: function(value) {
switch (typeof value) {
case 'boolean':
Expand Down
16 changes: 16 additions & 0 deletions src/micro/behaviors.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@

Polymer.Base._addFeature({

/**
* Array of objects to extend this prototype with.
*
* Each entry in the array may specify either a behavior object or array
* of behaviors.
*
* Each behavior object may define lifecycle callbacks, `properties`,
* `hostAttributes`, `observers` and `listeners`.
*
* Lifecycle callbacks will be called on the base prototype first, then
* for each behavior in the order given in the `behaviors` array.
* Additionally, any non-lifecycle functions on the behavior object are
* mixed into the base prototype, such that same-named functions on the
* prototype take precedence, followed by later behaviors over earlier
* behaviors.
*/
behaviors: [],

_prepBehaviors: function() {
Expand Down
7 changes: 7 additions & 0 deletions src/micro/extends.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@
return p;
},

/**
* Returns the native element prototype for the tag specified.
*
* @method getNativePrototype
* @param {string} tag HTML tag name.
* @return {Object} Native prototype for specified tag.
*/
getNativePrototype: function(tag) {
// TODO(sjmiles): sad necessity
return Object.getPrototypeOf(document.createElement(tag));
Expand Down
39 changes: 39 additions & 0 deletions src/micro/properties.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,48 @@

Polymer.Base._addFeature({

/*
* Object containing property configuration data, where keys are property
* names and values are descriptor objects that configure Polymer features
* for the property. Valid fields in the property descriptor object are
* as follows:
*
* * `type` - used to determine how to deserialize attribute value strings
* to JS properties. By convention, this field takes a JS constructor
* for the type, such as `String` or `Boolean`.
* * `notify` - when `true`, configures the property to fire a non-bubbling
* event called `<property>-changed` for each change to the property.
* Elements that have enabled two-way binding to the property use this
* event to observe changes.
* * `readOnly` - when `true` configures the property to have a getter, but
* no setter. To set a read-only property, use the private setter method
* `_set_<property>(value)`.
* * `reflectToAttribute` - when `true` configures the property to have a
* getter, but no setter. To set a read-only property, use the private
* setter method `_set_<property>(value)`.
* * `observer` - indicates the name of a funciton that should be called
* each time the property changes. `e.g.: `observer: 'valueChanged'
* * `computed` - configures the property to be computed by a computing
* function each time one or more dependent properties change.
* `e.g.: `computed: 'computeValue(prop1, prop2)'
*
* Note: a shorthand may be used for the object descriptor when only the
* type needs to be specified by using the type as the descriptor directly.
*/
properties: {
},

/**
* Returns a property descriptor object for the property specified.
*
* This method allows introspecting the configuration of a Polymer element's
* properties as configured in its `properties` object. Note, this method
* normalizes shorthand forms of the `properties` object into longhand form.
*
* @method getPropertyInfo
* @param {string} property Name of property to introspect.
* @return {Object} Property descriptor for specified property.
*/
getPropertyInfo: function(property) {
var info = this._getPropertyInfo(property, this.properties);
if (!info) {
Expand Down
18 changes: 16 additions & 2 deletions src/mini/ready.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@

_hostStack: [],

// for overriding
/**
* Lifecycle callback invoked when all local DOM children of this element
* have been created and "configured" with data bound from this element,
* attribute values, or defaults.
*
* @method ready
*/
ready: function() {
},

Expand Down Expand Up @@ -137,7 +143,15 @@
_afterClientsReady: function() {},
_beforeAttached: function() {},

// normalize lifecycle: ensure attached occurs only after ready.
/**
* Polymer library implementation of the Custom Elements `attachedCallback`.
*
* Note, users should not override `attachedCallback`, and instead should
* implement the `attached` method on Polymer elements to receive
* attached-time callbacks.
*
* @protected
*/
attachedCallback: function() {
if (this._readied) {
this._beforeAttached();
Expand Down
32 changes: 20 additions & 12 deletions src/mini/shady.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
_setupRoot: function() {
if (this._useContent) {
this._createLocalRoot();
// light elements may not be upgraded if they are light children
// and there is no configuration flow (no dataHost) and they are
// removed from document by shadyDOM distribution
// light elements may not be upgraded if they are light children
// and there is no configuration flow (no dataHost) and they are
// removed from document by shadyDOM distribution
// so we ensure this here
if (!this.dataHost) {
upgradeLightChildren(this._lightChildren);
Expand Down Expand Up @@ -79,9 +79,9 @@
* Force this element to distribute its children to its local dom.
* A user should call `distributeContent` if distribution has been
* invalidated due to changes to selectors on child elements that
* effect distribution that were not made via `Polymer.dom`.
* For example, if an element contains an insertion point with
* <content select=".foo"> and a `foo` class is added to a child,
* effect distribution that were not made via `Polymer.dom`.
* For example, if an element contains an insertion point with
* `<content select=".foo">` and a `foo` class is added to a child,
* then `distributeContent` must be called to update
* local dom distribution.
*/
Expand Down Expand Up @@ -142,10 +142,18 @@
}
},

// This is a polyfill for Element.prototype.matches, which is sometimes
// still prefixed. Alternatively we could just polyfill it somewhere.
// Note that the arguments are reversed from what you might expect.
/**
* Polyfill for Element.prototype.matches, which is sometimes still
* prefixed.
*
* @method elementMatches
* @param {string} selector Selector to test.
* @param {Element=} node Element to test the selector against.
* @return {boolean} Whether the element matches the selector.
*/
elementMatches: function(selector, node) {
// Alternatively we could just polyfill it somewhere.
// Note that the arguments are reversed from what you might expect.
node = node || this;
return matchesSelector.call(node, selector);
},
Expand Down Expand Up @@ -197,7 +205,7 @@
for (var i=0, l=p$.length, p; (i<l) && (p=p$[i]); i++) {
this._distributeInsertionPoint(p, pool);
// provoke redistribution on insertion point parents
// must do this on all candidate hosts since distribution in this
// must do this on all candidate hosts since distribution in this
// scope invalidates their distribution.
maybeRedistributeParent(p, this);
}
Expand Down Expand Up @@ -358,7 +366,7 @@
function maybeRedistributeParent(content, host) {
var parent = content._lightParent;
if (parent && parent.shadyRoot &&
hasInsertionPoint(parent.shadyRoot) &&
hasInsertionPoint(parent.shadyRoot) &&
parent.shadyRoot._distributionClean) {
parent.shadyRoot._distributionClean = false;
host.shadyRoot._dirtyRoots.push(parent);
Expand Down Expand Up @@ -417,7 +425,7 @@
return host;
}

// Return true if a host's children includes
// Return true if a host's children includes
// an insertion point that selects selectively
function hostNeedsRedistribution(host) {
var c$ = Polymer.dom(host).children;
Expand Down
Loading

0 comments on commit ec83143

Please sign in to comment.