1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

update polymer components

This commit is contained in:
Luke Pulverenti 2015-10-28 16:56:25 -04:00
parent 0320ad7256
commit 3c08769c6c
29 changed files with 961 additions and 844 deletions

View file

@ -29,14 +29,14 @@
"web-component-tester": "*", "web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
}, },
"homepage": "https://github.com/polymerelements/iron-a11y-keys-behavior", "homepage": "https://github.com/PolymerElements/iron-a11y-keys-behavior",
"_release": "1.0.8", "_release": "1.0.8",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "v1.0.8", "tag": "v1.0.8",
"commit": "df29a9edcff3b4693707f1e3eebce5a1dc46e946" "commit": "df29a9edcff3b4693707f1e3eebce5a1dc46e946"
}, },
"_source": "git://github.com/polymerelements/iron-a11y-keys-behavior.git", "_source": "git://github.com/PolymerElements/iron-a11y-keys-behavior.git",
"_target": "^1.0.0", "_target": "^1.0.0",
"_originalSource": "polymerelements/iron-a11y-keys-behavior" "_originalSource": "PolymerElements/iron-a11y-keys-behavior"
} }

View file

@ -1,12 +1,10 @@
{ {
"name": "iron-fit-behavior", "name": "iron-fit-behavior",
"version": "1.0.3", "version": "1.0.4",
"license": "http://polymer.github.io/LICENSE.txt", "license": "http://polymer.github.io/LICENSE.txt",
"description": "Fits an element inside another element", "description": "Fits an element inside another element",
"private": true, "private": true,
"main": [ "main": "iron-fit-behavior.html",
"iron-fit-behavior.html"
],
"keywords": [ "keywords": [
"web-components", "web-components",
"polymer", "polymer",
@ -30,11 +28,11 @@
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
}, },
"homepage": "https://github.com/PolymerElements/iron-fit-behavior", "homepage": "https://github.com/PolymerElements/iron-fit-behavior",
"_release": "1.0.3", "_release": "1.0.4",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "v1.0.3", "tag": "v1.0.4",
"commit": "df9fd83577ea6ebd98f5cad8333daa73dd0f34ba" "commit": "db76c6b9f3df86ee6dfc2339975313ac2efc6474"
}, },
"_source": "git://github.com/PolymerElements/iron-fit-behavior.git", "_source": "git://github.com/PolymerElements/iron-fit-behavior.git",
"_target": "^1.0.0", "_target": "^1.0.0",

View file

@ -1,12 +1,10 @@
{ {
"name": "iron-fit-behavior", "name": "iron-fit-behavior",
"version": "1.0.3", "version": "1.0.4",
"license": "http://polymer.github.io/LICENSE.txt", "license": "http://polymer.github.io/LICENSE.txt",
"description": "Fits an element inside another element", "description": "Fits an element inside another element",
"private": true, "private": true,
"main": [ "main": "iron-fit-behavior.html",
"iron-fit-behavior.html"
],
"keywords": [ "keywords": [
"web-components", "web-components",
"polymer", "polymer",

View file

@ -207,6 +207,10 @@ CSS properties | Action
if (!this._fitInfo.positionedBy.horizontally) { if (!this._fitInfo.positionedBy.horizontally) {
this.style.left = '0px'; this.style.left = '0px';
} }
if (!this._fitInfo.positionedBy.vertically || !this._fitInfo.positionedBy.horizontally) {
// need position:fixed to properly size the element
this.style.position = 'fixed';
}
// need border-box for margin/padding // need border-box for margin/padding
this.sizingTarget.style.boxSizing = 'border-box'; this.sizingTarget.style.boxSizing = 'border-box';
// constrain the width and height if not already set // constrain the width and height if not already set

View file

@ -149,6 +149,18 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</template> </template>
</test-fixture> </test-fixture>
<test-fixture id="offscreen-container">
<template>
<div style="position: fixed; top: -1px; left: 0;">
<test-fit auto-fit-on-attach class="el sized-x">
<div>
Sized (x), auto center/center, container is offscreen
</div>
</test-fit>
</div>
</template>
</test-fixture>
<template id="ipsum"> <template id="ipsum">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</template> </template>
@ -231,6 +243,15 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
assert.isTrue(rect.height <= window.innerHeight, 'height is less than or equal to viewport height'); assert.isTrue(rect.height <= window.innerHeight, 'height is less than or equal to viewport height');
}); });
test('scrolling element with offscreen container is constrained to viewport height', function() {
var container = fixture('offscreen-container');
var el = Polymer.dom(container).querySelector('.el')
makeScrolling(el);
el.refit();
var rect = el.getBoundingClientRect();
assert.isTrue(rect.height <= window.innerHeight, 'height is less than or equal to viewport height');
});
test('scrolling element with max-height is centered in viewport', function() { test('scrolling element with max-height is centered in viewport', function() {
var el = fixture('sized-x'); var el = fixture('sized-x');
el.classList.add('with-max-height'); el.classList.add('with-max-height');

View file

@ -25,14 +25,14 @@
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0", "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
"iron-component-page": "polymerelements/iron-component-page#^1.0.0" "iron-component-page": "polymerelements/iron-component-page#^1.0.0"
}, },
"homepage": "https://github.com/polymerelements/iron-flex-layout", "homepage": "https://github.com/PolymerElements/iron-flex-layout",
"_release": "1.0.4", "_release": "1.0.4",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "v1.0.4", "tag": "v1.0.4",
"commit": "dcfc54b0d358269bf0c72180b4ab090fc4931ecd" "commit": "dcfc54b0d358269bf0c72180b4ab090fc4931ecd"
}, },
"_source": "git://github.com/polymerelements/iron-flex-layout.git", "_source": "git://github.com/PolymerElements/iron-flex-layout.git",
"_target": "^1.0.0", "_target": "^1.0.0",
"_originalSource": "polymerelements/iron-flex-layout" "_originalSource": "PolymerElements/iron-flex-layout"
} }

View file

@ -1,6 +1,6 @@
{ {
"name": "iron-media-query", "name": "iron-media-query",
"version": "1.0.4", "version": "1.0.5",
"description": "Lets you bind to a CSS media query", "description": "Lets you bind to a CSS media query",
"authors": [ "authors": [
"The Polymer Authors" "The Polymer Authors"
@ -28,11 +28,12 @@
"iron-component-page": "PolymerElements/iron-component-page#^1.0.0", "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
}, },
"_release": "1.0.4", "main": "iron-media-query.html",
"_release": "1.0.5",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "v1.0.4", "tag": "v1.0.5",
"commit": "a9dd58cd50bb9f203a7beef15282bf74e48563a8" "commit": "2065bae0228149fc84db1c8ece741f9bba750534"
}, },
"_source": "git://github.com/PolymerElements/iron-media-query.git", "_source": "git://github.com/PolymerElements/iron-media-query.git",
"_target": "^1.0.0", "_target": "^1.0.0",

View file

@ -1,6 +1,6 @@
{ {
"name": "iron-media-query", "name": "iron-media-query",
"version": "1.0.4", "version": "1.0.5",
"description": "Lets you bind to a CSS media query", "description": "Lets you bind to a CSS media query",
"authors": [ "authors": [
"The Polymer Authors" "The Polymer Authors"
@ -27,5 +27,6 @@
"test-fixture": "PolymerElements/test-fixture#^1.0.0", "test-fixture": "PolymerElements/test-fixture#^1.0.0",
"iron-component-page": "PolymerElements/iron-component-page#^1.0.0", "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
} },
"main": "iron-media-query.html"
} }

View file

@ -29,17 +29,26 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<h1>&lt;iron-media-query&gt;</h1> <h1>&lt;iron-media-query&gt;</h1>
<template is="dom-bind"> <template is="dom-bind">
<iron-media-query query="(min-width: 600px)" query-matches="{{queryMatches}}"></iron-media-query> <iron-media-query query="(min-width: 600px)" query-matches="{{wide}}"></iron-media-query>
<iron-media-query full query="print" query-matches="{{print}}"></iron-media-query>
<template is="dom-if" if="{{queryMatches}}"> <template is="dom-if" if="{{wide}}">
<p>The viewports width is greater than <code>600px</code></p> <p>The viewports width is greater than <code>600px</code></p>
</template> </template>
<template is="dom-if" if="{{!queryMatches}}"> <template is="dom-if" if="{{!wide}}">
<p>The viewports width is less than <code>600px</code></p> <p>The viewports width is less than <code>600px</code></p>
</template> </template>
<p>
This link's destination is visible when printed:
<a href="http://polymer-project.org">Polymer Project</a>
<template is="dom-if" if="{{print}}">
(http://polymer-project.org)
</template>
</p>
</template> </template>
</div> </div>
</body> </body>
</html> </html>

View file

@ -49,6 +49,15 @@ Example:
type: String, type: String,
observer: 'queryChanged' observer: 'queryChanged'
}, },
/**
* If true, the query attribute is assumed to be a complete media query
* string rather than a single media feature.
*/
full: {
type: Boolean,
value: false
},
/** /**
* @type {function(MediaQueryList)} * @type {function(MediaQueryList)}
@ -94,7 +103,7 @@ Example:
if (!query) { if (!query) {
return; return;
} }
if (query[0] !== '(') { if (!this.full && query[0] !== '(') {
query = '(' + query + ')'; query = '(' + query + ')';
} }
this._mq = window.matchMedia(query); this._mq = window.matchMedia(query);

View file

@ -66,6 +66,20 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
assert.equal(mq.queryMatches, true); assert.equal(mq.queryMatches, true);
}); });
suite('`full` attribute', function() {
test('media features without wrapping parentheses no longer match', function() {
mq.full = true;
mq.query = 'min-width: 1px';
assert.equal(mq.queryMatches, false);
});
test('media queries with both types and features match', function() {
mq.full = true;
mq.query = 'all and (min-width: 1px)';
assert.equal(mq.queryMatches, true);
});
});
suite('query does not activate on empty string or null', function() { suite('query does not activate on empty string or null', function() {
test('empty string', function() { test('empty string', function() {

View file

@ -1,12 +1,10 @@
{ {
"name": "iron-selector", "name": "iron-selector",
"version": "1.0.7", "version": "1.0.8",
"description": "Manages a set of elements that can be selected", "description": "Manages a set of elements that can be selected",
"private": true, "private": true,
"license": "http://polymer.github.io/LICENSE.txt", "license": "http://polymer.github.io/LICENSE.txt",
"main": [ "main": "iron-selector.html",
"iron-selector.html"
],
"authors": [ "authors": [
"The Polymer Authors" "The Polymer Authors"
], ],
@ -22,7 +20,7 @@
"homepage": "https://github.com/PolymerElements/iron-selector", "homepage": "https://github.com/PolymerElements/iron-selector",
"ignore": [], "ignore": [],
"dependencies": { "dependencies": {
"polymer": "Polymer/polymer#^1.0.0" "polymer": "Polymer/polymer#^1.2.0"
}, },
"devDependencies": { "devDependencies": {
"iron-component-page": "PolymerElements/iron-component-page#^1.0.0", "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
@ -32,11 +30,11 @@
"web-component-tester": "*", "web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
}, },
"_release": "1.0.7", "_release": "1.0.8",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "v1.0.7", "tag": "v1.0.8",
"commit": "0b2f484ac3b1b03400da2d38b0f543f3688150a4" "commit": "e9a66727f3da0446f04956d4e4f1dcd51cdec2ff"
}, },
"_source": "git://github.com/PolymerElements/iron-selector.git", "_source": "git://github.com/PolymerElements/iron-selector.git",
"_target": "^1.0.0", "_target": "^1.0.0",

View file

@ -0,0 +1,28 @@
language: node_js
sudo: false
matrix:
include:
- node_js: stable
script: xvfb-run wct
addons:
firefox: latest
apt:
sources:
- google-chrome
packages:
- google-chrome-stable
- node_js: node
script:
- |
if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then
wct -s 'default'
fi
before_script:
- npm install web-component-tester
- npm install bower
- export PATH=$PWD/node_modules/.bin:$PATH
- bower install
env:
global:
- secure: ltCkwJM0nkTS9WjikyjqBsB5J2hQon4UnVVrINk4y+Vq4v9PQJH3+83nya0jnxilKaeAJs4d2/OS02F9GkqYpsSmDz7OgXPfk0hrHA8UksvvpSALfnukleIAN2YTOcxXJKeNHcfpqCKPk1dGeNQOEM61H+QgTBIyFB3sMugygqs=
- secure: TJuu1WdpFLTaBN/prBafm8Pld/BQCySNuuG1nATbF3fqiOpgehXu8Z5URAz5syUhqZAyEmuRMxvXpEVD/t1jrtaXVwkdCFkkQ4ckkP4gTIeSGA/Puw8sveB2q7QAqXyTmeFkocNlh8fxV+B07o0SPWdhcvdZnDVU9VrpSqL+92M=

View file

@ -1,12 +1,10 @@
{ {
"name": "iron-selector", "name": "iron-selector",
"version": "1.0.7", "version": "1.0.8",
"description": "Manages a set of elements that can be selected", "description": "Manages a set of elements that can be selected",
"private": true, "private": true,
"license": "http://polymer.github.io/LICENSE.txt", "license": "http://polymer.github.io/LICENSE.txt",
"main": [ "main": "iron-selector.html",
"iron-selector.html"
],
"authors": [ "authors": [
"The Polymer Authors" "The Polymer Authors"
], ],
@ -22,7 +20,7 @@
"homepage": "https://github.com/PolymerElements/iron-selector", "homepage": "https://github.com/PolymerElements/iron-selector",
"ignore": [], "ignore": [],
"dependencies": { "dependencies": {
"polymer": "Polymer/polymer#^1.0.0" "polymer": "Polymer/polymer#^1.2.0"
}, },
"devDependencies": { "devDependencies": {
"iron-component-page": "PolymerElements/iron-component-page#^1.0.0", "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",

View file

@ -72,6 +72,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
this._selection.multi = multi; this._selection.multi = multi;
}, },
get _shouldUpdateSelection() {
return this.selected != null ||
(this.selectedValues != null && this.selectedValues.length);
},
_updateSelected: function() { _updateSelected: function() {
if (this.multi) { if (this.multi) {
this._selectMulti(this.selectedValues); this._selectMulti(this.selectedValues);

View file

@ -64,6 +64,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
/** /**
* Returns the currently selected item. * Returns the currently selected item.
*
* @type {?Object}
*/ */
selectedItem: { selectedItem: {
type: Object, type: Object,
@ -104,11 +106,21 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
value: null value: null
}, },
/**
* The list of items from which a selection can be made.
*/
items: {
type: Array,
readOnly: true,
value: function() {
return [];
}
},
/** /**
* The set of excluded elements where the key is the `localName` * The set of excluded elements where the key is the `localName`
* of the element that will be ignored from the item list. * of the element that will be ignored from the item list.
* *
* @type {object}
* @default {template: 1} * @default {template: 1}
*/ */
_excludedLocalNames: { _excludedLocalNames: {
@ -128,15 +140,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
created: function() { created: function() {
this._bindFilterItem = this._filterItem.bind(this); this._bindFilterItem = this._filterItem.bind(this);
this._selection = new Polymer.IronSelection(this._applySelection.bind(this)); this._selection = new Polymer.IronSelection(this._applySelection.bind(this));
// TODO(cdata): When polymer/polymer#2535 lands, we do not need to do this
// book keeping anymore:
this.__listeningForActivate = false;
}, },
attached: function() { attached: function() {
this._observer = this._observeItems(this); this._observer = this._observeItems(this);
this._contentObserver = this._observeContent(this); this._updateItems();
if (!this.selectedItem && this.selected) { if (!this._shouldUpdateSelection) {
this._updateSelected(this.attrForSelected,this.selected) this._updateSelected(this.attrForSelected,this.selected)
} }
this._addListener(this.activateEvent); this._addListener(this.activateEvent);
@ -144,25 +153,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
detached: function() { detached: function() {
if (this._observer) { if (this._observer) {
this._observer.disconnect(); Polymer.dom(this).unobserveNodes(this._observer);
}
if (this._contentObserver) {
this._contentObserver.disconnect();
} }
this._removeListener(this.activateEvent); this._removeListener(this.activateEvent);
}, },
/**
* Returns an array of selectable items.
*
* @property items
* @type Array
*/
get items() {
var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*');
return Array.prototype.filter.call(nodes, this._bindFilterItem);
},
/** /**
* Returns the index of the given item. * Returns the index of the given item.
* *
@ -205,18 +200,16 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
this.selected = this._indexToValue(index); this.selected = this._indexToValue(index);
}, },
_addListener: function(eventName) { get _shouldUpdateSelection() {
if (!this.isAttached || this.__listeningForActivate) { return this.selected != null;
return; },
}
this.__listeningForActivate = true; _addListener: function(eventName) {
this.listen(this, eventName, '_activateHandler'); this.listen(this, eventName, '_activateHandler');
}, },
_removeListener: function(eventName) { _removeListener: function(eventName) {
this.unlisten(this, eventName, '_activateHandler'); this.unlisten(this, eventName, '_activateHandler');
this.__listeningForActivate = false;
}, },
_activateEventChanged: function(eventName, old) { _activateEventChanged: function(eventName, old) {
@ -224,6 +217,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
this._addListener(eventName); this._addListener(eventName);
}, },
_updateItems: function() {
var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*');
nodes = Array.prototype.filter.call(nodes, this._bindFilterItem);
this._setItems(nodes);
},
_updateSelected: function() { _updateSelected: function() {
this._selectSelected(this.selected); this._selectSelected(this.selected);
}, },
@ -282,18 +281,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
this._setSelectedItem(this._selection.get()); this._setSelectedItem(this._selection.get());
}, },
// observe content changes under the given node.
_observeContent: function(node) {
var content = node.querySelector('content');
if (content && content.parentElement === node) {
return this._observeItems(node.domHost);
}
},
// observe items change under the given node. // observe items change under the given node.
_observeItems: function(node) { _observeItems: function(node) {
// TODO(cdata): Update this when we get distributed children changed. return Polymer.dom(node).observeNodes(function(mutations) {
var observer = new MutationObserver(function(mutations) {
// Let other interested parties know about the change so that // Let other interested parties know about the change so that
// we don't have to recreate mutation observers everywher. // we don't have to recreate mutation observers everywher.
this.fire('iron-items-changed', mutations, { this.fire('iron-items-changed', mutations, {
@ -301,15 +291,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
cancelable: false cancelable: false
}); });
if (this.selected != null) { this._updateItems();
if (this._shouldUpdateSelection) {
this._updateSelected(); this._updateSelected();
} }
}.bind(this));
observer.observe(node, {
childList: true,
subtree: true
}); });
return observer;
}, },
_activateHandler: function(e) { _activateHandler: function(e) {

View file

@ -104,10 +104,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
s2 = fixture('basic'); s2 = fixture('basic');
}); });
test('honors the attrForSelected attribute', function() { test('honors the attrForSelected attribute', function(done) {
assert.equal(s2.attrForSelected, 'id'); Polymer.Base.async(function() {
assert.equal(s2.selected, 'item2'); assert.equal(s2.attrForSelected, 'id');
assert.equal(s2.selectedItem, document.querySelector('#item2')); assert.equal(s2.selected, 'item2');
assert.equal(s2.selectedItem, document.querySelector('#item2'));
done();
});
}); });
test('allows assignment to selected', function() { test('allows assignment to selected', function() {
@ -153,10 +156,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
changeCount++; changeCount++;
}); });
s2.appendChild(newItem); Polymer.dom(s2).appendChild(newItem);
Polymer.Base.async(function() { Polymer.Base.async(function() {
s2.removeChild(newItem); Polymer.dom(s2).removeChild(newItem);
Polymer.Base.async(function() { Polymer.Base.async(function() {
expect(changeCount).to.be.equal(2); expect(changeCount).to.be.equal(2);

View file

@ -70,17 +70,22 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
}); });
test('items', function() { test('items', function(done) {
test1._excludedLocalNames.span = 1; test1._excludedLocalNames.span = 1;
test2._excludedLocalNames.div = 1; test2._excludedLocalNames.div = 1;
test1._updateItems();
test2._updateItems();
Polymer.Base.async(function() {
var NOT_FOUND = -1; var NOT_FOUND = -1;
var items1 = test1.items.map(function(el) { return el.localName; }); var items1 = test1.items.map(function(el) { return el.localName; });
var items2 = test2.items.map(function(el) { return el.localName; }); var items2 = test2.items.map(function(el) { return el.localName; });
assert.equal(items1.indexOf('span'), NOT_FOUND); assert.equal(items1.indexOf('span'), NOT_FOUND);
assert.equal(items2.indexOf('div'), NOT_FOUND); assert.equal(items2.indexOf('div'), NOT_FOUND);
done();
}); });
});
}); });

View file

@ -66,6 +66,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
setup(function () { setup(function () {
s = fixture('test'); s = fixture('test');
t = Polymer.dom(s).querySelector('[is="dom-repeat"]');
}); });
test('honors the multi attribute', function() { test('honors the multi attribute', function() {
@ -163,6 +164,30 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
}); });
}); });
test('updates selection when dom changes', function(done) {
var selectEventCounter = 0;
s = fixture('test');
Polymer.Base.async(function() {
var firstChild = Polymer.dom(s).querySelector(':first-child');
var lastChild = Polymer.dom(s).querySelector(':last-child');
MockInteractions.tap(firstChild);
MockInteractions.tap(lastChild);
expect(s.selectedItems.length).to.be.equal(2);
Polymer.dom(s).removeChild(lastChild);
Polymer.Base.async(function() {
expect(s.selectedItems.length).to.be.equal(1);
done();
});
});
});
/* test('toggle multi from true to false', function() { /* test('toggle multi from true to false', function() {
// set selected // set selected
s.selected = [0, 2]; s.selected = [0, 2];

View file

@ -31,14 +31,14 @@
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0", "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
"iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0" "iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0"
}, },
"homepage": "https://github.com/PolymerElements/paper-ripple", "homepage": "https://github.com/polymerelements/paper-ripple",
"_release": "1.0.4", "_release": "1.0.4",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "v1.0.4", "tag": "v1.0.4",
"commit": "5f5893ca7bd6a8413d2f777c092a1a179b6bd45e" "commit": "5f5893ca7bd6a8413d2f777c092a1a179b6bd45e"
}, },
"_source": "git://github.com/PolymerElements/paper-ripple.git", "_source": "git://github.com/polymerelements/paper-ripple.git",
"_target": "^1.0.0", "_target": "^1.0.0",
"_originalSource": "PolymerElements/paper-ripple" "_originalSource": "polymerelements/paper-ripple"
} }

View file

@ -1,6 +1,6 @@
{ {
"name": "paper-spinner", "name": "paper-spinner",
"version": "1.0.2", "version": "1.0.3",
"description": "A material design spinner", "description": "A material design spinner",
"authors": [ "authors": [
"The Polymer Authors" "The Polymer Authors"
@ -22,19 +22,20 @@
"dependencies": { "dependencies": {
"iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0", "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
"paper-styles": "PolymerElements/paper-styles#^1.0.0", "paper-styles": "PolymerElements/paper-styles#^1.0.0",
"polymer": "Polymer/polymer#^1.0.0" "polymer": "Polymer/polymer#^1.1.0"
}, },
"devDependencies": { "devDependencies": {
"web-component-tester": "*",
"iron-component-page": "PolymerElements/iron-component-page#^1.0.0", "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
"test-fixture": "PolymerElements/test-fixture#^1.0.0", "test-fixture": "PolymerElements/test-fixture#^1.0.0",
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
}, },
"_release": "1.0.2", "main": "paper-spinner.html",
"_release": "1.0.3",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "v1.0.2", "tag": "v1.0.3",
"commit": "18bda194750ace719102d54c17ae1c6ce4a6793e" "commit": "33a5c598432642438c2ca90391dadb6d1d072887"
}, },
"_source": "git://github.com/PolymerElements/paper-spinner.git", "_source": "git://github.com/PolymerElements/paper-spinner.git",
"_target": "~1.0.1", "_target": "~1.0.1",

View file

@ -1,6 +1,6 @@
{ {
"name": "paper-spinner", "name": "paper-spinner",
"version": "1.0.2", "version": "1.0.3",
"description": "A material design spinner", "description": "A material design spinner",
"authors": [ "authors": [
"The Polymer Authors" "The Polymer Authors"
@ -22,12 +22,13 @@
"dependencies": { "dependencies": {
"iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0", "iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
"paper-styles": "PolymerElements/paper-styles#^1.0.0", "paper-styles": "PolymerElements/paper-styles#^1.0.0",
"polymer": "Polymer/polymer#^1.0.0" "polymer": "Polymer/polymer#^1.1.0"
}, },
"devDependencies": { "devDependencies": {
"web-component-tester": "*",
"iron-component-page": "PolymerElements/iron-component-page#^1.0.0", "iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
"test-fixture": "PolymerElements/test-fixture#^1.0.0", "test-fixture": "PolymerElements/test-fixture#^1.0.0",
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0" "webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
} },
"main": "paper-spinner.html"
} }

View file

@ -0,0 +1,337 @@
<!--
@license
Copyright (c) 2015 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
-->
<dom-module id="paper-spinner-styles">
<template>
<style>
/*
/**************************/
/* STYLES FOR THE SPINNER */
/**************************/
/*
* Constants:
* STROKEWIDTH = 3px
* ARCSIZE = 270 degrees (amount of circle the arc takes up)
* ARCTIME = 1333ms (time it takes to expand and contract arc)
* ARCSTARTROT = 216 degrees (how much the start location of the arc
* should rotate each time, 216 gives us a
* 5 pointed star shape (it's 360/5 * 3).
* For a 7 pointed star, we might do
* 360/7 * 3 = 154.286)
* CONTAINERWIDTH = 28px
* SHRINK_TIME = 400ms
*/
:host {
display: inline-block;
position: relative;
width: 28px; /* CONTAINERWIDTH */
height: 28px; /* CONTAINERWIDTH */
}
#spinnerContainer {
width: 100%;
height: 100%;
/* The spinner does not have any contents that would have to be
* flipped if the direction changes. Always use ltr so that the
* style works out correctly in both cases. */
direction: ltr;
}
#spinnerContainer.active {
/* duration: 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */
-webkit-animation: container-rotate 1568ms linear infinite;
animation: container-rotate 1568ms linear infinite;
}
@-webkit-keyframes container-rotate {
to { -webkit-transform: rotate(360deg) }
}
@keyframes container-rotate {
to { transform: rotate(360deg) }
}
.spinner-layer {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
}
.layer-1 {
border-color: var(--paper-spinner-layer-1-color, --google-blue-500);
}
.layer-2 {
border-color: var(--paper-spinner-layer-2-color, --google-red-500);
}
.layer-3 {
border-color: var(--paper-spinner-layer-3-color, --google-yellow-500);
}
.layer-4 {
border-color: var(--paper-spinner-layer-4-color, --google-green-500);
}
/**
* IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee):
*
* iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it doesn't
* guarantee that the animation will start _exactly_ after that value. So we avoid using
* animation-delay and instead set custom keyframes for each color (as layer-2undant as it
* seems).
*
* We write out each animation in full (instead of separating animation-name,
* animation-duration, etc.) because under the polyfill, Safari does not recognize those
* specific properties properly, treats them as -webkit-animation, and overrides the
* other animation rules. See https://github.com/Polymer/platform/issues/53.
*/
.active .spinner-layer.layer-1 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .spinner-layer.layer-2 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .spinner-layer.layer-3 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .spinner-layer.layer-4 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
@-webkit-keyframes fill-unfill-rotate {
12.5% { -webkit-transform: rotate(135deg); } /* 0.5 * ARCSIZE */
25% { -webkit-transform: rotate(270deg); } /* 1 * ARCSIZE */
37.5% { -webkit-transform: rotate(405deg); } /* 1.5 * ARCSIZE */
50% { -webkit-transform: rotate(540deg); } /* 2 * ARCSIZE */
62.5% { -webkit-transform: rotate(675deg); } /* 2.5 * ARCSIZE */
75% { -webkit-transform: rotate(810deg); } /* 3 * ARCSIZE */
87.5% { -webkit-transform: rotate(945deg); } /* 3.5 * ARCSIZE */
to { -webkit-transform: rotate(1080deg); } /* 4 * ARCSIZE */
}
@keyframes fill-unfill-rotate {
12.5% { transform: rotate(135deg); } /* 0.5 * ARCSIZE */
25% { transform: rotate(270deg); } /* 1 * ARCSIZE */
37.5% { transform: rotate(405deg); } /* 1.5 * ARCSIZE */
50% { transform: rotate(540deg); } /* 2 * ARCSIZE */
62.5% { transform: rotate(675deg); } /* 2.5 * ARCSIZE */
75% { transform: rotate(810deg); } /* 3 * ARCSIZE */
87.5% { transform: rotate(945deg); } /* 3.5 * ARCSIZE */
to { transform: rotate(1080deg); } /* 4 * ARCSIZE */
}
/**
* HACK: Even though the intention is to have the current .spinner-layer at
* `opacity: 1`, we set it to `opacity: 0.99` instead since this forces Chrome
* to do proper subpixel rendering for the elements being animated. This is
* especially visible in Chrome 39 on Ubuntu 14.04. See:
*
* - https://github.com/Polymer/paper-spinner/issues/9
* - https://code.google.com/p/chromium/issues/detail?id=436255
*/
@-webkit-keyframes layer-1-fade-in-out {
from { opacity: 0.99; }
25% { opacity: 0.99; }
26% { opacity: 0; }
89% { opacity: 0; }
90% { opacity: 0.99; }
100% { opacity: 0.99; }
}
@keyframes layer-1-fade-in-out {
from { opacity: 0.99; }
25% { opacity: 0.99; }
26% { opacity: 0; }
89% { opacity: 0; }
90% { opacity: 0.99; }
100% { opacity: 0.99; }
}
@-webkit-keyframes layer-2-fade-in-out {
from { opacity: 0; }
15% { opacity: 0; }
25% { opacity: 0.99; }
50% { opacity: 0.99; }
51% { opacity: 0; }
}
@keyframes layer-2-fade-in-out {
from { opacity: 0; }
15% { opacity: 0; }
25% { opacity: 0.99; }
50% { opacity: 0.99; }
51% { opacity: 0; }
}
@-webkit-keyframes layer-3-fade-in-out {
from { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 0.99; }
75% { opacity: 0.99; }
76% { opacity: 0; }
}
@keyframes layer-3-fade-in-out {
from { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 0.99; }
75% { opacity: 0.99; }
76% { opacity: 0; }
}
@-webkit-keyframes layer-4-fade-in-out {
from { opacity: 0; }
65% { opacity: 0; }
75% { opacity: 0.99; }
90% { opacity: 0.99; }
100% { opacity: 0; }
}
@keyframes layer-4-fade-in-out {
from { opacity: 0; }
65% { opacity: 0; }
75% { opacity: 0.99; }
90% { opacity: 0.99; }
100% { opacity: 0; }
}
/**
* Patch the gap that appear between the two adjacent div.circle-clipper while the
* spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11).
*
* Update: the gap no longer appears on Chrome when .spinner-layer's opacity is 0.99,
* but still does on Safari and IE.
*/
.gap-patch {
position: absolute;
box-sizing: border-box;
top: 0;
left: 45%;
width: 10%;
height: 100%;
overflow: hidden;
border-color: inherit;
}
.gap-patch .circle {
width: 1000%;
left: -450%;
}
.circle-clipper {
display: inline-block;
position: relative;
width: 50%;
height: 100%;
overflow: hidden;
border-color: inherit;
}
.circle-clipper .circle {
width: 200%;
}
.circle {
box-sizing: border-box;
height: 100%;
border-width: 3px; /* STROKEWIDTH */
border-style: solid;
border-color: inherit;
border-bottom-color: transparent !important;
border-radius: 50%;
-webkit-animation: none;
animation: none;
@apply(--layout-fit);
}
.circle-clipper.left .circle {
border-right-color: transparent !important;
-webkit-transform: rotate(129deg);
transform: rotate(129deg);
}
.circle-clipper.right .circle {
left: -100%;
border-left-color: transparent !important;
-webkit-transform: rotate(-129deg);
transform: rotate(-129deg);
}
.active .circle-clipper.left .circle {
/* duration: ARCTIME */
-webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .circle-clipper.right .circle {
/* duration: ARCTIME */
-webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
@-webkit-keyframes left-spin {
from { -webkit-transform: rotate(130deg); }
50% { -webkit-transform: rotate(-5deg); }
to { -webkit-transform: rotate(130deg); }
}
@keyframes left-spin {
from { transform: rotate(130deg); }
50% { transform: rotate(-5deg); }
to { transform: rotate(130deg); }
}
@-webkit-keyframes right-spin {
from { -webkit-transform: rotate(-130deg); }
50% { -webkit-transform: rotate(5deg); }
to { -webkit-transform: rotate(-130deg); }
}
@keyframes right-spin {
from { transform: rotate(-130deg); }
50% { transform: rotate(5deg); }
to { transform: rotate(-130deg); }
}
#spinnerContainer.cooldown {
/* duration: SHRINK_TIME */
-webkit-animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
}
@-webkit-keyframes fade-out {
from { opacity: 0.99; }
to { opacity: 0; }
}
@keyframes fade-out {
from { opacity: 0.99; }
to { opacity: 0; }
}
</style>
</template>
</dom-module>

View file

@ -1,330 +0,0 @@
/**
@license
Copyright (c) 2015 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
*/
/**************************/
/* STYLES FOR THE SPINNER */
/**************************/
/*
* Constants:
* STROKEWIDTH = 3px
* ARCSIZE = 270 degrees (amount of circle the arc takes up)
* ARCTIME = 1333ms (time it takes to expand and contract arc)
* ARCSTARTROT = 216 degrees (how much the start location of the arc
* should rotate each time, 216 gives us a
* 5 pointed star shape (it's 360/5 * 3).
* For a 7 pointed star, we might do
* 360/7 * 3 = 154.286)
* CONTAINERWIDTH = 28px
* SHRINK_TIME = 400ms
*/
:host {
display: inline-block;
position: relative;
width: 28px; /* CONTAINERWIDTH */
height: 28px; /* CONTAINERWIDTH */
}
#spinnerContainer {
width: 100%;
height: 100%;
/* The spinner does not have any contents that would have to be
* flipped if the direction changes. Always use ltr so that the
* style works out correctly in both cases. */
direction: ltr;
}
#spinnerContainer.active {
/* duration: 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */
-webkit-animation: container-rotate 1568ms linear infinite;
animation: container-rotate 1568ms linear infinite;
}
@-webkit-keyframes container-rotate {
to { -webkit-transform: rotate(360deg) }
}
@keyframes container-rotate {
to { transform: rotate(360deg) }
}
.spinner-layer {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
}
.layer-1 {
border-color: var(--paper-spinner-layer-1-color, --google-blue-500);
}
.layer-2 {
border-color: var(--paper-spinner-layer-2-color, --google-red-500);
}
.layer-3 {
border-color: var(--paper-spinner-layer-3-color, --google-yellow-500);
}
.layer-4 {
border-color: var(--paper-spinner-layer-4-color, --google-blue-500);
}
/**
* IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee):
*
* iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it doesn't
* guarantee that the animation will start _exactly_ after that value. So we avoid using
* animation-delay and instead set custom keyframes for each color (as layer-2undant as it
* seems).
*
* We write out each animation in full (instead of separating animation-name,
* animation-duration, etc.) because under the polyfill, Safari does not recognize those
* specific properties properly, treats them as -webkit-animation, and overrides the
* other animation rules. See https://github.com/Polymer/platform/issues/53.
*/
.active .spinner-layer.layer-1 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .spinner-layer.layer-2 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .spinner-layer.layer-3 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .spinner-layer.layer-4 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
@-webkit-keyframes fill-unfill-rotate {
12.5% { -webkit-transform: rotate(135deg); } /* 0.5 * ARCSIZE */
25% { -webkit-transform: rotate(270deg); } /* 1 * ARCSIZE */
37.5% { -webkit-transform: rotate(405deg); } /* 1.5 * ARCSIZE */
50% { -webkit-transform: rotate(540deg); } /* 2 * ARCSIZE */
62.5% { -webkit-transform: rotate(675deg); } /* 2.5 * ARCSIZE */
75% { -webkit-transform: rotate(810deg); } /* 3 * ARCSIZE */
87.5% { -webkit-transform: rotate(945deg); } /* 3.5 * ARCSIZE */
to { -webkit-transform: rotate(1080deg); } /* 4 * ARCSIZE */
}
@keyframes fill-unfill-rotate {
12.5% { transform: rotate(135deg); } /* 0.5 * ARCSIZE */
25% { transform: rotate(270deg); } /* 1 * ARCSIZE */
37.5% { transform: rotate(405deg); } /* 1.5 * ARCSIZE */
50% { transform: rotate(540deg); } /* 2 * ARCSIZE */
62.5% { transform: rotate(675deg); } /* 2.5 * ARCSIZE */
75% { transform: rotate(810deg); } /* 3 * ARCSIZE */
87.5% { transform: rotate(945deg); } /* 3.5 * ARCSIZE */
to { transform: rotate(1080deg); } /* 4 * ARCSIZE */
}
/**
* HACK: Even though the intention is to have the current .spinner-layer at
* `opacity: 1`, we set it to `opacity: 0.99` instead since this forces Chrome
* to do proper subpixel rendering for the elements being animated. This is
* especially visible in Chrome 39 on Ubuntu 14.04. See:
*
* - https://github.com/Polymer/paper-spinner/issues/9
* - https://code.google.com/p/chromium/issues/detail?id=436255
*/
@-webkit-keyframes layer-1-fade-in-out {
from { opacity: 0.99; }
25% { opacity: 0.99; }
26% { opacity: 0; }
89% { opacity: 0; }
90% { opacity: 0.99; }
100% { opacity: 0.99; }
}
@keyframes layer-1-fade-in-out {
from { opacity: 0.99; }
25% { opacity: 0.99; }
26% { opacity: 0; }
89% { opacity: 0; }
90% { opacity: 0.99; }
100% { opacity: 0.99; }
}
@-webkit-keyframes layer-2-fade-in-out {
from { opacity: 0; }
15% { opacity: 0; }
25% { opacity: 0.99; }
50% { opacity: 0.99; }
51% { opacity: 0; }
}
@keyframes layer-2-fade-in-out {
from { opacity: 0; }
15% { opacity: 0; }
25% { opacity: 0.99; }
50% { opacity: 0.99; }
51% { opacity: 0; }
}
@-webkit-keyframes layer-3-fade-in-out {
from { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 0.99; }
75% { opacity: 0.99; }
76% { opacity: 0; }
}
@keyframes layer-3-fade-in-out {
from { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 0.99; }
75% { opacity: 0.99; }
76% { opacity: 0; }
}
@-webkit-keyframes layer-4-fade-in-out {
from { opacity: 0; }
65% { opacity: 0; }
75% { opacity: 0.99; }
90% { opacity: 0.99; }
100% { opacity: 0; }
}
@keyframes layer-4-fade-in-out {
from { opacity: 0; }
65% { opacity: 0; }
75% { opacity: 0.99; }
90% { opacity: 0.99; }
100% { opacity: 0; }
}
/**
* Patch the gap that appear between the two adjacent div.circle-clipper while the
* spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11).
*
* Update: the gap no longer appears on Chrome when .spinner-layer's opacity is 0.99,
* but still does on Safari and IE.
*/
.gap-patch {
position: absolute;
box-sizing: border-box;
top: 0;
left: 45%;
width: 10%;
height: 100%;
overflow: hidden;
border-color: inherit;
}
.gap-patch .circle {
width: 1000%;
left: -450%;
}
.circle-clipper {
display: inline-block;
position: relative;
width: 50%;
height: 100%;
overflow: hidden;
border-color: inherit;
}
.circle-clipper .circle {
width: 200%;
}
.circle {
box-sizing: border-box;
height: 100%;
border-width: 3px; /* STROKEWIDTH */
border-style: solid;
border-color: inherit;
border-bottom-color: transparent !important;
border-radius: 50%;
-webkit-animation: none;
animation: none;
@apply(--layout-fit);
}
.circle-clipper.left .circle {
border-right-color: transparent !important;
-webkit-transform: rotate(129deg);
transform: rotate(129deg);
}
.circle-clipper.right .circle {
left: -100%;
border-left-color: transparent !important;
-webkit-transform: rotate(-129deg);
transform: rotate(-129deg);
}
.active .circle-clipper.left .circle {
/* duration: ARCTIME */
-webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .circle-clipper.right .circle {
/* duration: ARCTIME */
-webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
@-webkit-keyframes left-spin {
from { -webkit-transform: rotate(130deg); }
50% { -webkit-transform: rotate(-5deg); }
to { -webkit-transform: rotate(130deg); }
}
@keyframes left-spin {
from { transform: rotate(130deg); }
50% { transform: rotate(-5deg); }
to { transform: rotate(130deg); }
}
@-webkit-keyframes right-spin {
from { -webkit-transform: rotate(-130deg); }
50% { -webkit-transform: rotate(5deg); }
to { -webkit-transform: rotate(-130deg); }
}
@keyframes right-spin {
from { transform: rotate(-130deg); }
50% { transform: rotate(5deg); }
to { transform: rotate(-130deg); }
}
#spinnerContainer.cooldown {
/* duration: SHRINK_TIME */
-webkit-animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
}
@-webkit-keyframes fade-out {
from { opacity: 0.99; }
to { opacity: 0; }
}
@keyframes fade-out {
from { opacity: 0.99; }
to { opacity: 0; }
}

View file

@ -9,10 +9,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
--> -->
<link rel="import" href="../polymer/polymer.html"> <link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../paper-styles/color.html">
<link rel="import" href="../iron-flex-layout/iron-flex-layout.html"> <link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../paper-styles/color.html">
<link rel="import" href="paper-spinner-styles.html">
<!-- <!--
Material design: [Progress & activity](https://www.google.com/design/spec/components/progress-activity.html)
Element providing material design circular spinner. Element providing material design circular spinner.
<paper-spinner active></paper-spinner> <paper-spinner active></paper-spinner>
@ -48,10 +51,8 @@ Custom property | Description | Default
--> -->
<dom-module id="paper-spinner"> <dom-module id="paper-spinner">
<link rel="import" type="css" href="paper-spinner.css">
<template> <template>
<style include="paper-spinner-styles"></style>
<div id="spinnerContainer" class-name="[[_spinnerContainerClassName]]"> <div id="spinnerContainer" class-name="[[_spinnerContainerClassName]]">
<div class="spinner-layer layer-1"> <div class="spinner-layer layer-1">
@ -94,13 +95,10 @@ Custom property | Description | Default
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
Polymer({ Polymer({
is: 'paper-spinner', is: 'paper-spinner',
listeners: { listeners: {
@ -109,7 +107,6 @@ Custom property | Description | Default
}, },
properties: { properties: {
/** /**
* Displays the spinner. * Displays the spinner.
* *
@ -152,7 +149,6 @@ Custom property | Description | Default
type: String, type: String,
computed: '_computeSpinnerContainerClassName(active, _coolingDown)' computed: '_computeSpinnerContainerClassName(active, _coolingDown)'
} }
}, },
_computeSpinnerContainerClassName: function(active, coolingDown) { _computeSpinnerContainerClassName: function(active, coolingDown) {
@ -164,9 +160,7 @@ Custom property | Description | Default
_activeChanged: function(active, old) { _activeChanged: function(active, old) {
this._setAriaHidden(!active); this._setAriaHidden(!active);
if (!active && old) { this._coolingDown = !active && old;
this._coolingDown = true;
}
}, },
_altChanged: function(alt) { _altChanged: function(alt) {
@ -192,9 +186,6 @@ Custom property | Description | Default
this.active = false; this.active = false;
this._coolingDown = false; this._coolingDown = false;
} }
}); });
</script> </script>
</dom-module> </dom-module>

View file

@ -31,6 +31,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</template> </template>
</test-fixture> </test-fixture>
<test-fixture id="ActivePaperSpinner">
<template>
<paper-spinner active></paper-spinner>
</template>
</test-fixture>
<script> <script>
'use strict'; 'use strict';
@ -38,9 +44,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
suite('an accessible paper spinner', function() { suite('an accessible paper spinner', function() {
var spinner; var spinner;
var activeSpinner;
setup(function() { setup(function() {
spinner = fixture('PaperSpinner'); spinner = fixture('PaperSpinner');
activeSpinner = fixture('ActivePaperSpinner');
}); });
test('adds an ARIA label when `alt` is supplied', function() { test('adds an ARIA label when `alt` is supplied', function() {
@ -54,6 +62,21 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
spinner.active = false; spinner.active = false;
expect(spinner.getAttribute('aria-hidden')).to.be.eql('true'); expect(spinner.getAttribute('aria-hidden')).to.be.eql('true');
}); });
test('toggle during cooldown', function(done) {
activeSpinner.active = false;
// Set active to true before cooldown animation completes.
setTimeout(function() {
activeSpinner.active = true;
// Wait for cooldown animation to complete.
setTimeout(function() {
expect(activeSpinner.active).to.equal(true);
done();
}, 500);
}, 100);
});
}); });
}); });

View file

@ -97,9 +97,9 @@
}).fail(function (e) { }).fail(function (e) {
alert('validate fail');
if (e.status == 402) { if (e.status == 402) {
alert('validate fail - expired');
callback(false, { callback(false, {
code: store.PURCHASE_EXPIRED, code: store.PURCHASE_EXPIRED,
error: { error: {
@ -107,6 +107,8 @@
} }
}); });
} else { } else {
alert('validate fail - other');
callback(false, { callback(false, {
code: store.CONNECTION_FAILED, code: store.CONNECTION_FAILED,
error: { error: {

View file

@ -514,13 +514,13 @@ var Dashboard = {
} else { } else {
// IE renders it incorrectly // IE renders it incorrectly
if (!$.browser.msie && !$.browser.edge) { //if (!$.browser.msie && !$.browser.edge) {
elem = document.createElement("paper-spinner"); elem = document.createElement("paper-spinner");
elem.classList.add('docspinner'); elem.classList.add('docspinner');
document.body.appendChild(elem); document.body.appendChild(elem);
elem.active = true; elem.active = true;
} //}
} }
}, },

View file

@ -10197,6 +10197,10 @@ CSS properties | Action
if (!this._fitInfo.positionedBy.horizontally) { if (!this._fitInfo.positionedBy.horizontally) {
this.style.left = '0px'; this.style.left = '0px';
} }
if (!this._fitInfo.positionedBy.vertically || !this._fitInfo.positionedBy.horizontally) {
// need position:fixed to properly size the element
this.style.position = 'fixed';
}
// need border-box for margin/padding // need border-box for margin/padding
this.sizingTarget.style.boxSizing = 'border-box'; this.sizingTarget.style.boxSizing = 'border-box';
// constrain the width and height if not already set // constrain the width and height if not already set
@ -11558,6 +11562,8 @@ The `aria-labelledby` attribute will be set to the header element, if one exists
/** /**
* Returns the currently selected item. * Returns the currently selected item.
*
* @type {?Object}
*/ */
selectedItem: { selectedItem: {
type: Object, type: Object,
@ -11598,11 +11604,21 @@ The `aria-labelledby` attribute will be set to the header element, if one exists
value: null value: null
}, },
/**
* The list of items from which a selection can be made.
*/
items: {
type: Array,
readOnly: true,
value: function() {
return [];
}
},
/** /**
* The set of excluded elements where the key is the `localName` * The set of excluded elements where the key is the `localName`
* of the element that will be ignored from the item list. * of the element that will be ignored from the item list.
* *
* @type {object}
* @default {template: 1} * @default {template: 1}
*/ */
_excludedLocalNames: { _excludedLocalNames: {
@ -11622,15 +11638,12 @@ The `aria-labelledby` attribute will be set to the header element, if one exists
created: function() { created: function() {
this._bindFilterItem = this._filterItem.bind(this); this._bindFilterItem = this._filterItem.bind(this);
this._selection = new Polymer.IronSelection(this._applySelection.bind(this)); this._selection = new Polymer.IronSelection(this._applySelection.bind(this));
// TODO(cdata): When polymer/polymer#2535 lands, we do not need to do this
// book keeping anymore:
this.__listeningForActivate = false;
}, },
attached: function() { attached: function() {
this._observer = this._observeItems(this); this._observer = this._observeItems(this);
this._contentObserver = this._observeContent(this); this._updateItems();
if (!this.selectedItem && this.selected) { if (!this._shouldUpdateSelection) {
this._updateSelected(this.attrForSelected,this.selected) this._updateSelected(this.attrForSelected,this.selected)
} }
this._addListener(this.activateEvent); this._addListener(this.activateEvent);
@ -11638,25 +11651,11 @@ The `aria-labelledby` attribute will be set to the header element, if one exists
detached: function() { detached: function() {
if (this._observer) { if (this._observer) {
this._observer.disconnect(); Polymer.dom(this).unobserveNodes(this._observer);
}
if (this._contentObserver) {
this._contentObserver.disconnect();
} }
this._removeListener(this.activateEvent); this._removeListener(this.activateEvent);
}, },
/**
* Returns an array of selectable items.
*
* @property items
* @type Array
*/
get items() {
var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*');
return Array.prototype.filter.call(nodes, this._bindFilterItem);
},
/** /**
* Returns the index of the given item. * Returns the index of the given item.
* *
@ -11699,18 +11698,16 @@ The `aria-labelledby` attribute will be set to the header element, if one exists
this.selected = this._indexToValue(index); this.selected = this._indexToValue(index);
}, },
_addListener: function(eventName) { get _shouldUpdateSelection() {
if (!this.isAttached || this.__listeningForActivate) { return this.selected != null;
return; },
}
this.__listeningForActivate = true; _addListener: function(eventName) {
this.listen(this, eventName, '_activateHandler'); this.listen(this, eventName, '_activateHandler');
}, },
_removeListener: function(eventName) { _removeListener: function(eventName) {
this.unlisten(this, eventName, '_activateHandler'); this.unlisten(this, eventName, '_activateHandler');
this.__listeningForActivate = false;
}, },
_activateEventChanged: function(eventName, old) { _activateEventChanged: function(eventName, old) {
@ -11718,6 +11715,12 @@ The `aria-labelledby` attribute will be set to the header element, if one exists
this._addListener(eventName); this._addListener(eventName);
}, },
_updateItems: function() {
var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '*');
nodes = Array.prototype.filter.call(nodes, this._bindFilterItem);
this._setItems(nodes);
},
_updateSelected: function() { _updateSelected: function() {
this._selectSelected(this.selected); this._selectSelected(this.selected);
}, },
@ -11776,18 +11779,9 @@ The `aria-labelledby` attribute will be set to the header element, if one exists
this._setSelectedItem(this._selection.get()); this._setSelectedItem(this._selection.get());
}, },
// observe content changes under the given node.
_observeContent: function(node) {
var content = node.querySelector('content');
if (content && content.parentElement === node) {
return this._observeItems(node.domHost);
}
},
// observe items change under the given node. // observe items change under the given node.
_observeItems: function(node) { _observeItems: function(node) {
// TODO(cdata): Update this when we get distributed children changed. return Polymer.dom(node).observeNodes(function(mutations) {
var observer = new MutationObserver(function(mutations) {
// Let other interested parties know about the change so that // Let other interested parties know about the change so that
// we don't have to recreate mutation observers everywher. // we don't have to recreate mutation observers everywher.
this.fire('iron-items-changed', mutations, { this.fire('iron-items-changed', mutations, {
@ -11795,15 +11789,12 @@ The `aria-labelledby` attribute will be set to the header element, if one exists
cancelable: false cancelable: false
}); });
if (this.selected != null) { this._updateItems();
if (this._shouldUpdateSelection) {
this._updateSelected(); this._updateSelected();
} }
}.bind(this));
observer.observe(node, {
childList: true,
subtree: true
}); });
return observer;
}, },
_activateHandler: function(e) { _activateHandler: function(e) {
@ -11902,6 +11893,15 @@ The `aria-labelledby` attribute will be set to the header element, if one exists
type: String, type: String,
observer: 'queryChanged' observer: 'queryChanged'
}, },
/**
* If true, the query attribute is assumed to be a complete media query
* string rather than a single media feature.
*/
full: {
type: Boolean,
value: false
},
/** /**
* @type {function(MediaQueryList)} * @type {function(MediaQueryList)}
@ -11947,7 +11947,7 @@ The `aria-labelledby` attribute will be set to the header element, if one exists
if (!query) { if (!query) {
return; return;
} }
if (query[0] !== '(') { if (!this.full && query[0] !== '(') {
query = '(' + query + ')'; query = '(' + query + ')';
} }
this._mq = window.matchMedia(query); this._mq = window.matchMedia(query);
@ -12023,6 +12023,11 @@ The `aria-labelledby` attribute will be set to the header element, if one exists
this._selection.multi = multi; this._selection.multi = multi;
}, },
get _shouldUpdateSelection() {
return this.selected != null ||
(this.selectedValues != null && this.selectedValues.length);
},
_updateSelected: function() { _updateSelected: function() {
if (this.multi) { if (this.multi) {
this._selectMulti(this.selectedValues); this._selectMulti(this.selectedValues);
@ -14897,343 +14902,336 @@ is separate from validation, and `allowed-pattern` does not affect how the input
})(); })();
</script> </script>
<dom-module id="paper-spinner" assetpath="bower_components/paper-spinner/"> <dom-module id="paper-spinner-styles" assetpath="bower_components/paper-spinner/">
<style>
/**
@license
Copyright (c) 2015 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
*/
/**************************/
/* STYLES FOR THE SPINNER */
/**************************/
/*
* Constants:
* STROKEWIDTH = 3px
* ARCSIZE = 270 degrees (amount of circle the arc takes up)
* ARCTIME = 1333ms (time it takes to expand and contract arc)
* ARCSTARTROT = 216 degrees (how much the start location of the arc
* should rotate each time, 216 gives us a
* 5 pointed star shape (it's 360/5 * 3).
* For a 7 pointed star, we might do
* 360/7 * 3 = 154.286)
* CONTAINERWIDTH = 28px
* SHRINK_TIME = 400ms
*/
:host {
display: inline-block;
position: relative;
width: 28px; /* CONTAINERWIDTH */
height: 28px; /* CONTAINERWIDTH */
}
#spinnerContainer {
width: 100%;
height: 100%;
/* The spinner does not have any contents that would have to be
* flipped if the direction changes. Always use ltr so that the
* style works out correctly in both cases. */
direction: ltr;
}
#spinnerContainer.active {
/* duration: 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */
-webkit-animation: container-rotate 1568ms linear infinite;
animation: container-rotate 1568ms linear infinite;
}
@-webkit-keyframes container-rotate {
to { -webkit-transform: rotate(360deg) }
}
@keyframes container-rotate {
to { transform: rotate(360deg) }
}
.spinner-layer {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
}
.layer-1 {
border-color: var(--paper-spinner-layer-1-color, --google-blue-500);
}
.layer-2 {
border-color: var(--paper-spinner-layer-2-color, --google-red-500);
}
.layer-3 {
border-color: var(--paper-spinner-layer-3-color, --google-yellow-500);
}
.layer-4 {
border-color: var(--paper-spinner-layer-4-color, --google-blue-500);
}
/**
* IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee):
*
* iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it doesn't
* guarantee that the animation will start _exactly_ after that value. So we avoid using
* animation-delay and instead set custom keyframes for each color (as layer-2undant as it
* seems).
*
* We write out each animation in full (instead of separating animation-name,
* animation-duration, etc.) because under the polyfill, Safari does not recognize those
* specific properties properly, treats them as -webkit-animation, and overrides the
* other animation rules. See https://github.com/Polymer/platform/issues/53.
*/
.active .spinner-layer.layer-1 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .spinner-layer.layer-2 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .spinner-layer.layer-3 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .spinner-layer.layer-4 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
@-webkit-keyframes fill-unfill-rotate {
12.5% { -webkit-transform: rotate(135deg); } /* 0.5 * ARCSIZE */
25% { -webkit-transform: rotate(270deg); } /* 1 * ARCSIZE */
37.5% { -webkit-transform: rotate(405deg); } /* 1.5 * ARCSIZE */
50% { -webkit-transform: rotate(540deg); } /* 2 * ARCSIZE */
62.5% { -webkit-transform: rotate(675deg); } /* 2.5 * ARCSIZE */
75% { -webkit-transform: rotate(810deg); } /* 3 * ARCSIZE */
87.5% { -webkit-transform: rotate(945deg); } /* 3.5 * ARCSIZE */
to { -webkit-transform: rotate(1080deg); } /* 4 * ARCSIZE */
}
@keyframes fill-unfill-rotate {
12.5% { transform: rotate(135deg); } /* 0.5 * ARCSIZE */
25% { transform: rotate(270deg); } /* 1 * ARCSIZE */
37.5% { transform: rotate(405deg); } /* 1.5 * ARCSIZE */
50% { transform: rotate(540deg); } /* 2 * ARCSIZE */
62.5% { transform: rotate(675deg); } /* 2.5 * ARCSIZE */
75% { transform: rotate(810deg); } /* 3 * ARCSIZE */
87.5% { transform: rotate(945deg); } /* 3.5 * ARCSIZE */
to { transform: rotate(1080deg); } /* 4 * ARCSIZE */
}
/**
* HACK: Even though the intention is to have the current .spinner-layer at
* `opacity: 1`, we set it to `opacity: 0.99` instead since this forces Chrome
* to do proper subpixel rendering for the elements being animated. This is
* especially visible in Chrome 39 on Ubuntu 14.04. See:
*
* - https://github.com/Polymer/paper-spinner/issues/9
* - https://code.google.com/p/chromium/issues/detail?id=436255
*/
@-webkit-keyframes layer-1-fade-in-out {
from { opacity: 0.99; }
25% { opacity: 0.99; }
26% { opacity: 0; }
89% { opacity: 0; }
90% { opacity: 0.99; }
100% { opacity: 0.99; }
}
@keyframes layer-1-fade-in-out {
from { opacity: 0.99; }
25% { opacity: 0.99; }
26% { opacity: 0; }
89% { opacity: 0; }
90% { opacity: 0.99; }
100% { opacity: 0.99; }
}
@-webkit-keyframes layer-2-fade-in-out {
from { opacity: 0; }
15% { opacity: 0; }
25% { opacity: 0.99; }
50% { opacity: 0.99; }
51% { opacity: 0; }
}
@keyframes layer-2-fade-in-out {
from { opacity: 0; }
15% { opacity: 0; }
25% { opacity: 0.99; }
50% { opacity: 0.99; }
51% { opacity: 0; }
}
@-webkit-keyframes layer-3-fade-in-out {
from { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 0.99; }
75% { opacity: 0.99; }
76% { opacity: 0; }
}
@keyframes layer-3-fade-in-out {
from { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 0.99; }
75% { opacity: 0.99; }
76% { opacity: 0; }
}
@-webkit-keyframes layer-4-fade-in-out {
from { opacity: 0; }
65% { opacity: 0; }
75% { opacity: 0.99; }
90% { opacity: 0.99; }
100% { opacity: 0; }
}
@keyframes layer-4-fade-in-out {
from { opacity: 0; }
65% { opacity: 0; }
75% { opacity: 0.99; }
90% { opacity: 0.99; }
100% { opacity: 0; }
}
/**
* Patch the gap that appear between the two adjacent div.circle-clipper while the
* spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11).
*
* Update: the gap no longer appears on Chrome when .spinner-layer's opacity is 0.99,
* but still does on Safari and IE.
*/
.gap-patch {
position: absolute;
box-sizing: border-box;
top: 0;
left: 45%;
width: 10%;
height: 100%;
overflow: hidden;
border-color: inherit;
}
.gap-patch .circle {
width: 1000%;
left: -450%;
}
.circle-clipper {
display: inline-block;
position: relative;
width: 50%;
height: 100%;
overflow: hidden;
border-color: inherit;
}
.circle-clipper .circle {
width: 200%;
}
.circle {
box-sizing: border-box;
height: 100%;
border-width: 3px; /* STROKEWIDTH */
border-style: solid;
border-color: inherit;
border-bottom-color: transparent !important;
border-radius: 50%;
-webkit-animation: none;
animation: none;
@apply(--layout-fit);
}
.circle-clipper.left .circle {
border-right-color: transparent !important;
-webkit-transform: rotate(129deg);
transform: rotate(129deg);
}
.circle-clipper.right .circle {
left: -100%;
border-left-color: transparent !important;
-webkit-transform: rotate(-129deg);
transform: rotate(-129deg);
}
.active .circle-clipper.left .circle {
/* duration: ARCTIME */
-webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .circle-clipper.right .circle {
/* duration: ARCTIME */
-webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
@-webkit-keyframes left-spin {
from { -webkit-transform: rotate(130deg); }
50% { -webkit-transform: rotate(-5deg); }
to { -webkit-transform: rotate(130deg); }
}
@keyframes left-spin {
from { transform: rotate(130deg); }
50% { transform: rotate(-5deg); }
to { transform: rotate(130deg); }
}
@-webkit-keyframes right-spin {
from { -webkit-transform: rotate(-130deg); }
50% { -webkit-transform: rotate(5deg); }
to { -webkit-transform: rotate(-130deg); }
}
@keyframes right-spin {
from { transform: rotate(-130deg); }
50% { transform: rotate(5deg); }
to { transform: rotate(-130deg); }
}
#spinnerContainer.cooldown {
/* duration: SHRINK_TIME */
-webkit-animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
}
@-webkit-keyframes fade-out {
from { opacity: 0.99; }
to { opacity: 0; }
}
@keyframes fade-out {
from { opacity: 0.99; }
to { opacity: 0; }
}
</style>
<template> <template>
<style>
/*
/**************************/
/* STYLES FOR THE SPINNER */
/**************************/
/*
* Constants:
* STROKEWIDTH = 3px
* ARCSIZE = 270 degrees (amount of circle the arc takes up)
* ARCTIME = 1333ms (time it takes to expand and contract arc)
* ARCSTARTROT = 216 degrees (how much the start location of the arc
* should rotate each time, 216 gives us a
* 5 pointed star shape (it's 360/5 * 3).
* For a 7 pointed star, we might do
* 360/7 * 3 = 154.286)
* CONTAINERWIDTH = 28px
* SHRINK_TIME = 400ms
*/
:host {
display: inline-block;
position: relative;
width: 28px; /* CONTAINERWIDTH */
height: 28px; /* CONTAINERWIDTH */
}
#spinnerContainer {
width: 100%;
height: 100%;
/* The spinner does not have any contents that would have to be
* flipped if the direction changes. Always use ltr so that the
* style works out correctly in both cases. */
direction: ltr;
}
#spinnerContainer.active {
/* duration: 360 * ARCTIME / (ARCSTARTROT + (360-ARCSIZE)) */
-webkit-animation: container-rotate 1568ms linear infinite;
animation: container-rotate 1568ms linear infinite;
}
@-webkit-keyframes container-rotate {
to { -webkit-transform: rotate(360deg) }
}
@keyframes container-rotate {
to { transform: rotate(360deg) }
}
.spinner-layer {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
}
.layer-1 {
border-color: var(--paper-spinner-layer-1-color, --google-blue-500);
}
.layer-2 {
border-color: var(--paper-spinner-layer-2-color, --google-red-500);
}
.layer-3 {
border-color: var(--paper-spinner-layer-3-color, --google-yellow-500);
}
.layer-4 {
border-color: var(--paper-spinner-layer-4-color, --google-green-500);
}
/**
* IMPORTANT NOTE ABOUT CSS ANIMATION PROPERTIES (keanulee):
*
* iOS Safari (tested on iOS 8.1) does not handle animation-delay very well - it doesn't
* guarantee that the animation will start _exactly_ after that value. So we avoid using
* animation-delay and instead set custom keyframes for each color (as layer-2undant as it
* seems).
*
* We write out each animation in full (instead of separating animation-name,
* animation-duration, etc.) because under the polyfill, Safari does not recognize those
* specific properties properly, treats them as -webkit-animation, and overrides the
* other animation rules. See https://github.com/Polymer/platform/issues/53.
*/
.active .spinner-layer.layer-1 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-1-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .spinner-layer.layer-2 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-2-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .spinner-layer.layer-3 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-3-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .spinner-layer.layer-4 {
/* durations: 4 * ARCTIME */
-webkit-animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: fill-unfill-rotate 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both, layer-4-fade-in-out 5332ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
@-webkit-keyframes fill-unfill-rotate {
12.5% { -webkit-transform: rotate(135deg); } /* 0.5 * ARCSIZE */
25% { -webkit-transform: rotate(270deg); } /* 1 * ARCSIZE */
37.5% { -webkit-transform: rotate(405deg); } /* 1.5 * ARCSIZE */
50% { -webkit-transform: rotate(540deg); } /* 2 * ARCSIZE */
62.5% { -webkit-transform: rotate(675deg); } /* 2.5 * ARCSIZE */
75% { -webkit-transform: rotate(810deg); } /* 3 * ARCSIZE */
87.5% { -webkit-transform: rotate(945deg); } /* 3.5 * ARCSIZE */
to { -webkit-transform: rotate(1080deg); } /* 4 * ARCSIZE */
}
@keyframes fill-unfill-rotate {
12.5% { transform: rotate(135deg); } /* 0.5 * ARCSIZE */
25% { transform: rotate(270deg); } /* 1 * ARCSIZE */
37.5% { transform: rotate(405deg); } /* 1.5 * ARCSIZE */
50% { transform: rotate(540deg); } /* 2 * ARCSIZE */
62.5% { transform: rotate(675deg); } /* 2.5 * ARCSIZE */
75% { transform: rotate(810deg); } /* 3 * ARCSIZE */
87.5% { transform: rotate(945deg); } /* 3.5 * ARCSIZE */
to { transform: rotate(1080deg); } /* 4 * ARCSIZE */
}
/**
* HACK: Even though the intention is to have the current .spinner-layer at
* `opacity: 1`, we set it to `opacity: 0.99` instead since this forces Chrome
* to do proper subpixel rendering for the elements being animated. This is
* especially visible in Chrome 39 on Ubuntu 14.04. See:
*
* - https://github.com/Polymer/paper-spinner/issues/9
* - https://code.google.com/p/chromium/issues/detail?id=436255
*/
@-webkit-keyframes layer-1-fade-in-out {
from { opacity: 0.99; }
25% { opacity: 0.99; }
26% { opacity: 0; }
89% { opacity: 0; }
90% { opacity: 0.99; }
100% { opacity: 0.99; }
}
@keyframes layer-1-fade-in-out {
from { opacity: 0.99; }
25% { opacity: 0.99; }
26% { opacity: 0; }
89% { opacity: 0; }
90% { opacity: 0.99; }
100% { opacity: 0.99; }
}
@-webkit-keyframes layer-2-fade-in-out {
from { opacity: 0; }
15% { opacity: 0; }
25% { opacity: 0.99; }
50% { opacity: 0.99; }
51% { opacity: 0; }
}
@keyframes layer-2-fade-in-out {
from { opacity: 0; }
15% { opacity: 0; }
25% { opacity: 0.99; }
50% { opacity: 0.99; }
51% { opacity: 0; }
}
@-webkit-keyframes layer-3-fade-in-out {
from { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 0.99; }
75% { opacity: 0.99; }
76% { opacity: 0; }
}
@keyframes layer-3-fade-in-out {
from { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 0.99; }
75% { opacity: 0.99; }
76% { opacity: 0; }
}
@-webkit-keyframes layer-4-fade-in-out {
from { opacity: 0; }
65% { opacity: 0; }
75% { opacity: 0.99; }
90% { opacity: 0.99; }
100% { opacity: 0; }
}
@keyframes layer-4-fade-in-out {
from { opacity: 0; }
65% { opacity: 0; }
75% { opacity: 0.99; }
90% { opacity: 0.99; }
100% { opacity: 0; }
}
/**
* Patch the gap that appear between the two adjacent div.circle-clipper while the
* spinner is rotating (appears on Chrome 38, Safari 7.1, and IE 11).
*
* Update: the gap no longer appears on Chrome when .spinner-layer's opacity is 0.99,
* but still does on Safari and IE.
*/
.gap-patch {
position: absolute;
box-sizing: border-box;
top: 0;
left: 45%;
width: 10%;
height: 100%;
overflow: hidden;
border-color: inherit;
}
.gap-patch .circle {
width: 1000%;
left: -450%;
}
.circle-clipper {
display: inline-block;
position: relative;
width: 50%;
height: 100%;
overflow: hidden;
border-color: inherit;
}
.circle-clipper .circle {
width: 200%;
}
.circle {
box-sizing: border-box;
height: 100%;
border-width: 3px; /* STROKEWIDTH */
border-style: solid;
border-color: inherit;
border-bottom-color: transparent !important;
border-radius: 50%;
-webkit-animation: none;
animation: none;
@apply(--layout-fit);
}
.circle-clipper.left .circle {
border-right-color: transparent !important;
-webkit-transform: rotate(129deg);
transform: rotate(129deg);
}
.circle-clipper.right .circle {
left: -100%;
border-left-color: transparent !important;
-webkit-transform: rotate(-129deg);
transform: rotate(-129deg);
}
.active .circle-clipper.left .circle {
/* duration: ARCTIME */
-webkit-animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: left-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
.active .circle-clipper.right .circle {
/* duration: ARCTIME */
-webkit-animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
animation: right-spin 1333ms cubic-bezier(0.4, 0.0, 0.2, 1) infinite both;
}
@-webkit-keyframes left-spin {
from { -webkit-transform: rotate(130deg); }
50% { -webkit-transform: rotate(-5deg); }
to { -webkit-transform: rotate(130deg); }
}
@keyframes left-spin {
from { transform: rotate(130deg); }
50% { transform: rotate(-5deg); }
to { transform: rotate(130deg); }
}
@-webkit-keyframes right-spin {
from { -webkit-transform: rotate(-130deg); }
50% { -webkit-transform: rotate(5deg); }
to { -webkit-transform: rotate(-130deg); }
}
@keyframes right-spin {
from { transform: rotate(-130deg); }
50% { transform: rotate(5deg); }
to { transform: rotate(-130deg); }
}
#spinnerContainer.cooldown {
/* duration: SHRINK_TIME */
-webkit-animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
animation: container-rotate 1568ms linear infinite, fade-out 400ms cubic-bezier(0.4, 0.0, 0.2, 1);
}
@-webkit-keyframes fade-out {
from { opacity: 0.99; }
to { opacity: 0; }
}
@keyframes fade-out {
from { opacity: 0.99; }
to { opacity: 0; }
}
</style>
</template>
</dom-module>
<dom-module id="paper-spinner" assetpath="bower_components/paper-spinner/">
<template>
<style include="paper-spinner-styles"></style>
<div id="spinnerContainer" class-name="[[_spinnerContainerClassName]]"> <div id="spinnerContainer" class-name="[[_spinnerContainerClassName]]">
<div class="spinner-layer layer-1"> <div class="spinner-layer layer-1">
@ -15276,13 +15274,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
Polymer({ Polymer({
is: 'paper-spinner', is: 'paper-spinner',
listeners: { listeners: {
@ -15291,7 +15286,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
}, },
properties: { properties: {
/** /**
* Displays the spinner. * Displays the spinner.
* *
@ -15334,7 +15328,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
type: String, type: String,
computed: '_computeSpinnerContainerClassName(active, _coolingDown)' computed: '_computeSpinnerContainerClassName(active, _coolingDown)'
} }
}, },
_computeSpinnerContainerClassName: function(active, coolingDown) { _computeSpinnerContainerClassName: function(active, coolingDown) {
@ -15346,9 +15339,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
_activeChanged: function(active, old) { _activeChanged: function(active, old) {
this._setAriaHidden(!active); this._setAriaHidden(!active);
if (!active && old) { this._coolingDown = !active && old;
this._coolingDown = true;
}
}, },
_altChanged: function(alt) { _altChanged: function(alt) {
@ -15374,11 +15365,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
this.active = false; this.active = false;
this._coolingDown = false; this._coolingDown = false;
} }
}); });
</script> </script>
</dom-module> </dom-module>
<dom-module id="iron-icon" assetpath="bower_components/iron-icon/"> <dom-module id="iron-icon" assetpath="bower_components/iron-icon/">