Commit 6cce0138 authored by Pascal Hartig's avatar Pascal Hartig Committed by Sindre Sorhus

Bump Polymer dependencies

parent 2b868b1a
......@@ -3,7 +3,8 @@
"dependencies": {
"jquery": "~2.1.0",
"bootstrap": "~3.2.0",
"paper-tabs": "Polymer/paper-tabs#~0.4.0"
"paper-tabs": "polymerelements/paper-tabs#~1.0.10",
"iron-pages": "polymerelements/iron-pages#~1.0.3"
},
"devDependencies": {
"prefixfree": "91790e8aff6d807cd62018479db2307e1972b92a"
......
{
"name": "core-selection",
"private": true,
"dependencies": {
"polymer": "Polymer/polymer#^0.4.0"
},
"devDependencies": {
"polymer-test-tools": "Polymer/polymer-test-tools#master"
},
"homepage": "https://github.com/Polymer/core-selection",
"version": "0.4.1",
"_release": "0.4.1",
"_resolution": {
"type": "version",
"tag": "0.4.1",
"commit": "dd6919363a49f1f4ff52fa0dffef88e2bdfbbfdc"
},
"_source": "git://github.com/Polymer/core-selection.git",
"_target": "^0.4.0",
"_originalSource": "Polymer/core-selection"
}
\ No newline at end of file
core-selection
==============
See the [component page](http://polymer-project.org/docs/elements/core-elements.html#core-selection) for more information.
{
"name": "core-selection",
"private": true,
"dependencies": {
"polymer": "Polymer/polymer#^0.4.0"
},
"devDependencies": {
"polymer-test-tools": "Polymer/polymer-test-tools#master"
}
}
\ No newline at end of file
<!--
Copyright (c) 2014 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
-->
<!--
@group Polymer Core Elements
The `<core-selection>` element is used to manage selection state. It has no
visual appearance and is typically used in conjunction with another element.
For example, [core-selector](#core-selector)
use a `<core-selection>` to manage selection.
To mark an item as selected, call the `select(item)` method on
`<core-selection>`. The item itself is an argument to this method.
The `<core-selection>`element manages selection state for any given set of
items. When an item is selected, the `core-select` event is fired.
The attribute `multi` indicates if multiple items can be selected at once.
Example:
<polymer-element name="selection-example">
<template>
<style>
polyfill-next-selector { content: ':host > .selected'; }
::content > .selected {
font-weight: bold;
font-style: italic;
}
</style>
<ul on-tap="{{itemTapAction}}">
<content></content>
</ul>
<core-selection id="selection" multi
on-core-select="{{selectAction}}"></core-selection>
</template>
<script>
Polymer('selection-example', {
itemTapAction: function(e, detail, sender) {
this.$.selection.select(e.target);
},
selectAction: function(e, detail, sender) {
detail.item.classList.toggle('selected', detail.isSelected);
}
});
</script>
</polymer-element>
<selection-example>
<li>Red</li>
<li>Green</li>
<li>Blue</li>
</selection-example>
@element core-selection
-->
<!--
Fired when an item's selection state is changed. This event is fired both
when an item is selected or deselected. The `isSelected` detail property
contains the selection state.
@event core-select
@param {Object} detail
@param {boolean} detail.isSelected true for selection and false for de-selection
@param {Object} detail.item the item element
-->
<link rel="import" href="../polymer/polymer.html">
<polymer-element name="core-selection" attributes="multi" hidden>
<script>
Polymer('core-selection', {
/**
* If true, multiple selections are allowed.
*
* @attribute multi
* @type boolean
* @default false
*/
multi: false,
ready: function() {
this.clear();
},
clear: function() {
this.selection = [];
},
/**
* Retrieves the selected item(s).
* @method getSelection
* @returns Returns the selected item(s). If the multi property is true,
* getSelection will return an array, otherwise it will return
* the selected item or undefined if there is no selection.
*/
getSelection: function() {
return this.multi ? this.selection : this.selection[0];
},
/**
* Indicates if a given item is selected.
* @method isSelected
* @param {any} item The item whose selection state should be checked.
* @returns Returns true if `item` is selected.
*/
isSelected: function(item) {
return this.selection.indexOf(item) >= 0;
},
setItemSelected: function(item, isSelected) {
if (item !== undefined && item !== null) {
if (isSelected) {
this.selection.push(item);
} else {
var i = this.selection.indexOf(item);
if (i >= 0) {
this.selection.splice(i, 1);
}
}
this.fire("core-select", {isSelected: isSelected, item: item});
}
},
/**
* Set the selection state for a given `item`. If the multi property
* is true, then the selected state of `item` will be toggled; otherwise
* the `item` will be selected.
* @method select
* @param {any} item: The item to select.
*/
select: function(item) {
if (this.multi) {
this.toggle(item);
} else if (this.getSelection() !== item) {
this.setItemSelected(this.getSelection(), false);
this.setItemSelected(item, true);
}
},
/**
* Toggles the selection state for `item`.
* @method toggle
* @param {any} item: The item to toggle.
*/
toggle: function(item) {
this.setItemSelected(item, !this.isSelected(item));
}
});
</script>
</polymer-element>
<!DOCTYPE html>
<!--
Copyright (c) 2014 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
-->
<html>
<head>
<title>Selection</title>
<script src="../platform/platform.js"></script>
<link rel="import" href="core-selection.html">
</head>
<body unresolved>
<polymer-element name="selection-example">
<template>
<style>
polyfill-next-selector { content: 'ul > *'; }
::content > * {
cursor: pointer;
}
polyfill-next-selector { content: 'ul > .selected'; }
::content > .selected {
font-weight: bold;
font-style: italic;
}
</style>
<ul on-tap="{{itemTapAction}}">
<content></content>
</ul>
<core-selection id="selection" multi on-core-select="{{selectAction}}"></core-selection>
</template>
<script>
Polymer('selection-example', {
itemTapAction: function(e, detail, sender) {
this.$.selection.select(e.target);
},
selectAction: function(e, detail, sender) {
detail.item.classList.toggle('selected', detail.isSelected);
}
});
</script>
</polymer-element>
<selection-example>
<li>Red</li>
<li>Green</li>
<li>Blue</li>
</selection-example>
</body>
</html>
<!doctype html>
<!--
Copyright (c) 2014 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
The complete set of authors may be found at http://polymer.github.io/AUTHORS
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
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
-->
<html>
<head>
<script src="../platform/platform.js"></script>
<link rel="import" href="../core-component-page/core-component-page.html">
</head>
<body unresolved>
<core-component-page></core-component-page>
</body>
</html>
{
"name": "core-selector",
"private": true,
"dependencies": {
"polymer": "Polymer/polymer#^0.4.0",
"core-selection": "Polymer/core-selection#^0.4.0"
},
"devDependencies": {
"polymer-test-tools": "Polymer/polymer-test-tools#master"
},
"homepage": "https://github.com/Polymer/core-selector",
"version": "0.4.1",
"_release": "0.4.1",
"_resolution": {
"type": "version",
"tag": "0.4.1",
"commit": "7d2a5d5b127d0ed3feb7bcb0bdaaeb95c4499cc9"
},
"_source": "git://github.com/Polymer/core-selector.git",
"_target": "^0.4.0",
"_originalSource": "Polymer/core-selector"
}
\ No newline at end of file
core-selector
==============
See the [component page](http://polymer-project.org/docs/elements/core-elements.html#core-selector) for more information.
{
"name": "core-selector",
"private": true,
"dependencies": {
"polymer": "Polymer/polymer#^0.4.0",
"core-selection": "Polymer/core-selection#^0.4.0"
},
"devDependencies": {
"polymer-test-tools": "Polymer/polymer-test-tools#master"
}
}
\ No newline at end of file
<!--
Copyright (c) 2014 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
-->
<!--
@group Polymer Core Elements
`<core-selector>` is used to manage a list of elements that can be selected.
The attribute `selected` indicates which item element is being selected.
The attribute `multi` indicates if multiple items can be selected at once.
Tapping on the item element would fire `core-activate` event. Use
`core-select` event to listen for selection changes.
Example:
<core-selector selected="0">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</core-selector>
`<core-selector>` is not styled. Use the `core-selected` CSS class to style the selected element.
<style>
.item.core-selected {
background: #eee;
}
</style>
...
<core-selector>
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
</core-selector>
@element core-selector
@status stable
@homepage github.io
-->
<!--
Fired when an item's selection state is changed. This event is fired both
when an item is selected or deselected. The `isSelected` detail property
contains the selection state.
@event core-select
@param {Object} detail
@param {boolean} detail.isSelected true for selection and false for deselection
@param {Object} detail.item the item element
-->
<!--
Fired when an item element is tapped.
@event core-activate
@param {Object} detail
@param {Object} detail.item the item element
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../core-selection/core-selection.html">
<polymer-element name="core-selector"
attributes="selected multi valueattr selectedClass selectedProperty selectedAttribute selectedItem selectedModel selectedIndex notap excludedLocalNames target itemsSelector activateEvent">
<template>
<core-selection id="selection" multi="{{multi}}" on-core-select="{{selectionSelect}}"></core-selection>
<content id="items" select="*"></content>
</template>
<script>
Polymer('core-selector', {
/**
* Gets or sets the selected element. Default to use the index
* of the item element.
*
* If you want a specific attribute value of the element to be
* used instead of index, set "valueattr" to that attribute name.
*
* Example:
*
* <core-selector valueattr="label" selected="foo">
* <div label="foo"></div>
* <div label="bar"></div>
* <div label="zot"></div>
* </core-selector>
*
* In multi-selection this should be an array of values.
*
* Example:
*
* <core-selector id="selector" valueattr="label" multi>
* <div label="foo"></div>
* <div label="bar"></div>
* <div label="zot"></div>
* </core-selector>
*
* this.$.selector.selected = ['foo', 'zot'];
*
* @attribute selected
* @type Object
* @default null
*/
selected: null,
/**
* If true, multiple selections are allowed.
*
* @attribute multi
* @type boolean
* @default false
*/
multi: false,
/**
* Specifies the attribute to be used for "selected" attribute.
*
* @attribute valueattr
* @type string
* @default 'name'
*/
valueattr: 'name',
/**
* Specifies the CSS class to be used to add to the selected element.
*
* @attribute selectedClass
* @type string
* @default 'core-selected'
*/
selectedClass: 'core-selected',
/**
* Specifies the property to be used to set on the selected element
* to indicate its active state.
*
* @attribute selectedProperty
* @type string
* @default ''
*/
selectedProperty: '',
/**
* Specifies the attribute to set on the selected element to indicate
* its active state.
*
* @attribute selectedAttribute
* @type string
* @default 'active'
*/
selectedAttribute: 'active',
/**
* Returns the currently selected element. In multi-selection this returns
* an array of selected elements.
* Note that you should not use this to set the selection. Instead use
* `selected`.
*
* @attribute selectedItem
* @type Object
* @default null
*/
selectedItem: null,
/**
* In single selection, this returns the model associated with the
* selected element.
* Note that you should not use this to set the selection. Instead use
* `selected`.
*
* @attribute selectedModel
* @type Object
* @default null
*/
selectedModel: null,
/**
* In single selection, this returns the selected index.
* Note that you should not use this to set the selection. Instead use
* `selected`.
*
* @attribute selectedIndex
* @type number
* @default -1
*/
selectedIndex: -1,
/**
* Nodes with local name that are in the list will not be included
* in the selection items. In the following example, `items` returns four
* `core-item`'s and doesn't include `h3` and `hr`.
*
* <core-selector excludedLocalNames="h3 hr">
* <h3>Header</h3>
* <core-item>Item1</core-item>
* <core-item>Item2</core-item>
* <hr>
* <core-item>Item3</core-item>
* <core-item>Item4</core-item>
* </core-selector>
*
* @attribute excludedLocalNames
* @type string
* @default ''
*/
excludedLocalNames: '',
/**
* The target element that contains items. If this is not set
* core-selector is the container.
*
* @attribute target
* @type Object
* @default null
*/
target: null,
/**
* This can be used to query nodes from the target node to be used for
* selection items. Note this only works if `target` is set
* and is not `core-selector` itself.
*
* Example:
*
* <core-selector target="{{$.myForm}}" itemsSelector="input[type=radio]"></core-selector>
* <form id="myForm">
* <label><input type="radio" name="color" value="red"> Red</label> <br>
* <label><input type="radio" name="color" value="green"> Green</label> <br>
* <label><input type="radio" name="color" value="blue"> Blue</label> <br>
* <p>color = {{color}}</p>
* </form>
*
* @attribute itemsSelector
* @type string
* @default ''
*/
itemsSelector: '',
/**
* The event that would be fired from the item element to indicate
* it is being selected.
*
* @attribute activateEvent
* @type string
* @default 'tap'
*/
activateEvent: 'tap',
/**
* Set this to true to disallow changing the selection via the
* `activateEvent`.
*
* @attribute notap
* @type boolean
* @default false
*/
notap: false,
defaultExcludedLocalNames: 'template',
ready: function() {
this.activateListener = this.activateHandler.bind(this);
this.itemFilter = this.filterItem.bind(this);
this.excludedLocalNamesChanged();
this.observer = new MutationObserver(this.updateSelected.bind(this));
if (!this.target) {
this.target = this;
}
},
/**
* Returns an array of all items.
*
* @property items
*/
get items() {
if (!this.target) {
return [];
}
var nodes = this.target !== this ? (this.itemsSelector ?
this.target.querySelectorAll(this.itemsSelector) :
this.target.children) : this.$.items.getDistributedNodes();
return Array.prototype.filter.call(nodes, this.itemFilter);
},
filterItem: function(node) {
return !this._excludedNames[node.localName];
},
excludedLocalNamesChanged: function() {
this._excludedNames = {};
var s = this.defaultExcludedLocalNames;
if (this.excludedLocalNames) {
s += ' ' + this.excludedLocalNames;
}
s.split(/\s+/g).forEach(function(n) {
this._excludedNames[n] = 1;
}, this);
},
targetChanged: function(old) {
if (old) {
this.removeListener(old);
this.observer.disconnect();
this.clearSelection();
}
if (this.target) {
this.addListener(this.target);
this.observer.observe(this.target, {childList: true});
this.updateSelected();
}
},
addListener: function(node) {
Polymer.addEventListener(node, this.activateEvent, this.activateListener);
},
removeListener: function(node) {
Polymer.removeEventListener(node, this.activateEvent, this.activateListener);
},
/**
* Returns the selected item(s). If the `multi` property is true,
* this will return an array, otherwise it will return
* the selected item or undefined if there is no selection.
*/
get selection() {
return this.$.selection.getSelection();
},
selectedChanged: function() {
this.updateSelected();
},
updateSelected: function() {
this.validateSelected();
if (this.multi) {
this.clearSelection();
this.selected && this.selected.forEach(function(s) {
this.valueToSelection(s);
}, this);
} else {
this.valueToSelection(this.selected);
}
},
validateSelected: function() {
// convert to an array for multi-selection
if (this.multi && !Array.isArray(this.selected) &&
this.selected !== null && this.selected !== undefined) {
this.selected = [this.selected];
}
},
clearSelection: function() {
if (this.multi) {
this.selection.slice().forEach(function(s) {
this.$.selection.setItemSelected(s, false);
}, this);
} else {
this.$.selection.setItemSelected(this.selection, false);
}
this.selectedItem = null;
this.$.selection.clear();
},
valueToSelection: function(value) {
var item = (value === null || value === undefined) ?
null : this.items[this.valueToIndex(value)];
this.$.selection.select(item);
},
updateSelectedItem: function() {
this.selectedItem = this.selection;
},
selectedItemChanged: function() {
if (this.selectedItem) {
var t = this.selectedItem.templateInstance;
this.selectedModel = t ? t.model : undefined;
} else {
this.selectedModel = null;
}
this.selectedIndex = this.selectedItem ?
parseInt(this.valueToIndex(this.selected)) : -1;
},
valueToIndex: function(value) {
// find an item with value == value and return it's index
for (var i=0, items=this.items, c; (c=items[i]); i++) {
if (this.valueForNode(c) == value) {
return i;
}
}
// if no item found, the value itself is probably the index
return value;
},
valueForNode: function(node) {
return node[this.valueattr] || node.getAttribute(this.valueattr);
},
// events fired from <core-selection> object
selectionSelect: function(e, detail) {
this.updateSelectedItem();
if (detail.item) {
this.applySelection(detail.item, detail.isSelected);
}
},
applySelection: function(item, isSelected) {
if (this.selectedClass) {
item.classList.toggle(this.selectedClass, isSelected);
}
if (this.selectedProperty) {
item[this.selectedProperty] = isSelected;
}
if (this.selectedAttribute && item.setAttribute) {
if (isSelected) {
item.setAttribute(this.selectedAttribute, '');
} else {
item.removeAttribute(this.selectedAttribute);
}
}
},
// event fired from host
activateHandler: function(e) {
if (!this.notap) {
var i = this.findDistributedTarget(e.target, this.items);
if (i >= 0) {
var item = this.items[i];
var s = this.valueForNode(item) || i;
if (this.multi) {
if (this.selected) {
this.addRemoveSelected(s);
} else {
this.selected = [s];
}
} else {
this.selected = s;
}
this.asyncFire('core-activate', {item: item});
}
}
},
addRemoveSelected: function(value) {
var i = this.selected.indexOf(value);
if (i >= 0) {
this.selected.splice(i, 1);
} else {
this.selected.push(value);
}
this.valueToSelection(value);
},
findDistributedTarget: function(target, nodes) {
// find first ancestor of target (including itself) that
// is in nodes, if any
while (target && target != this) {
var i = Array.prototype.indexOf.call(nodes, target);
if (i >= 0) {
return i;
}
target = target.parentNode;
}
},
selectIndex: function(index) {
var item = this.items[index];
if (item) {
this.selected = this.valueForNode(item) || index;
return item;
}
},
/**
* Selects the previous item. This should be used in single selection only.
*
* @method selectPrevious
* @param {boolean} wrap if true and it is already at the first item, wrap to the end
* @returns the previous item or undefined if there is none
*/
selectPrevious: function(wrap) {
var i = wrap && !this.selectedIndex ? this.items.length - 1 : this.selectedIndex - 1;
return this.selectIndex(i);
},
/**
* Selects the next item. This should be used in single selection only.
*
* @method selectNext
* @param {boolean} wrap if true and it is already at the last item, wrap to the front
* @returns the next item or undefined if there is none
*/
selectNext: function(wrap) {
var i = wrap && this.selectedIndex >= this.items.length - 1 ? 0 : this.selectedIndex + 1;
return this.selectIndex(i);
}
});
</script>
</polymer-element>
<!DOCTYPE html>
<!--
Copyright (c) 2014 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
-->
<html>
<head>
<title>Selector</title>
<script src="../platform/platform.js"></script>
<link rel="import" href="core-selector.html">
</head>
<body unresolved>
<polymer-element name="selector-examples">
<template>
<style>
.list {
display: block;
border: 1px solid #ccc;
border-bottom: none;
background: #666;
color: white;
list-style: none;
margin: 0;
padding: 0;
}
.list > * {
height: 40px;
line-height: 40px;
padding: 0 20px;
border-bottom: 1px solid #ccc;
}
.list > *.core-selected {
background: #333;
}
li {
height: 30px;
}
li.core-selected:after {
content: "\2713";
position: absolute;
padding-left: 10px;
}
</style>
<h2>basic</h2>
<core-selector class="list" selected="0">
<div>Item 0</div>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</core-selector>
<h2>multi-selection</h2>
<core-selector class="list" selected="{{multiSelected}}" multi>
<div>Item 0</div>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</core-selector>
<h2>list</h2>
<core-selector target="{{$.list}}" selected="0"></core-selector>
<ul id="list">
<li>Item 0</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
<h2>binding of a group of radio buttons to a variable</h2>
<core-selector target="{{$.myForm}}" itemsSelector="input[type=radio]"
selected="{{color}}" valueattr="value" selectedProperty="checked"
activateEvent="change"></core-selector>
<form id="myForm">
<label><input type="radio" name="color" value="red"> Red</label> <br>
<label><input type="radio" name="color" value="green"> Green</label> <br>
<label><input type="radio" name="color" value="blue"> Blue</label> <br>
<p>color = {{color}}</p>
</form>
</template>
<script>
Polymer('selector-examples', {
ready: function() {
this.multiSelected = [1, 3];
this.color = 'green';
}
});
</script>
</polymer-element>
<selector-examples></selector-examples>
</body>
</html>
<!doctype html>
<!--
Copyright (c) 2014 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
The complete set of authors may be found at http://polymer.github.io/AUTHORS
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
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
-->
<html>
<head>
<script src="../platform/platform.js"></script>
<link rel="import" href="../core-component-page/core-component-page.html">
</head>
<body unresolved>
<core-component-page></core-component-page>
</body>
</html>
<!--
@license
Copyright (c) 2014 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
-->
<x-meta id="core-selector" label="Selector" group="Core" isContainer>
<template>
<core-selector selected="0" style="width:100%;height:50px;"></core-selector>
</template>
<template>
<link rel="import" href="core-selector.html">
</template>
</x-meta>
\ No newline at end of file
/*!
* jQuery JavaScript Library v2.1.1
* jQuery JavaScript Library v2.1.4
* http://jquery.com/
*
* Includes Sizzle.js
......@@ -9,19 +9,19 @@
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2014-05-01T17:11Z
* Date: 2015-04-28T16:01Z
*/
(function( global, factory ) {
if ( typeof module === "object" && typeof module.exports === "object" ) {
// For CommonJS and CommonJS-like environments where a proper window is present,
// execute the factory and get jQuery
// For environments that do not inherently posses a window with a document
// (such as Node.js), expose a jQuery-making factory as module.exports
// This accentuates the need for the creation of a real window
// For CommonJS and CommonJS-like environments where a proper `window`
// is present, execute the factory and get jQuery.
// For environments that do not have a `window` with a `document`
// (such as Node.js), expose a factory as module.exports.
// This accentuates the need for the creation of a real `window`.
// e.g. var jQuery = require("jquery")(window);
// See ticket #14549 for more info
// See ticket #14549 for more info.
module.exports = global.document ?
factory( global, true ) :
function( w ) {
......@@ -37,10 +37,10 @@
// Pass this if window is not defined yet
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
// Can't do this because several apps including ASP.NET trace
// Support: Firefox 18+
// Can't be in strict mode, several libs including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if
// you try to trace through "use strict" call chains. (#13335)
// Support: Firefox 18+
//
var arr = [];
......@@ -67,7 +67,7 @@ var
// Use the correct document accordingly with window argument (sandbox)
document = window.document,
version = "2.1.1",
version = "2.1.4",
// Define a local copy of jQuery
jQuery = function( selector, context ) {
......@@ -185,7 +185,7 @@ jQuery.extend = jQuery.fn.extend = function() {
if ( typeof target === "boolean" ) {
deep = target;
// skip the boolean and the target
// Skip the boolean and the target
target = arguments[ i ] || {};
i++;
}
......@@ -195,7 +195,7 @@ jQuery.extend = jQuery.fn.extend = function() {
target = {};
}
// extend jQuery itself if only one argument is passed
// Extend jQuery itself if only one argument is passed
if ( i === length ) {
target = this;
i--;
......@@ -252,9 +252,6 @@ jQuery.extend({
noop: function() {},
// See test/unit/core.js for details concerning isFunction.
// Since version 1.3, DOM methods and functions like alert
// aren't supported. They return false on IE (#2968).
isFunction: function( obj ) {
return jQuery.type(obj) === "function";
},
......@@ -269,7 +266,8 @@ jQuery.extend({
// parseFloat NaNs numeric-cast false positives (null|true|false|"")
// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
// subtraction forces infinities to NaN
return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0;
// adding 1 corrects loss of precision from parseFloat (#15100)
return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
},
isPlainObject: function( obj ) {
......@@ -303,7 +301,7 @@ jQuery.extend({
if ( obj == null ) {
return obj + "";
}
// Support: Android < 4.0, iOS < 6 (functionish RegExp)
// Support: Android<4.0, iOS<6 (functionish RegExp)
return typeof obj === "object" || typeof obj === "function" ?
class2type[ toString.call(obj) ] || "object" :
typeof obj;
......@@ -333,6 +331,7 @@ jQuery.extend({
},
// Convert dashed to camelCase; used by the css and data modules
// Support: IE9-11+
// Microsoft forgot to hump their vendor prefix (#9572)
camelCase: function( string ) {
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
......@@ -532,7 +531,12 @@ jQuery.each("Boolean Number String Function Array Date RegExp Object Error".spli
});
function isArraylike( obj ) {
var length = obj.length,
// Support: iOS 8.2 (not reproducible in simulator)
// `in` check used to prevent JIT error (gh-2145)
// hasOwn isn't used here due to false negatives
// regarding Nodelist length in IE
var length = "length" in obj && obj.length,
type = jQuery.type( obj );
if ( type === "function" || jQuery.isWindow( obj ) ) {
......@@ -548,14 +552,14 @@ function isArraylike( obj ) {
}
var Sizzle =
/*!
* Sizzle CSS Selector Engine v1.10.19
* Sizzle CSS Selector Engine v2.2.0-pre
* http://sizzlejs.com/
*
* Copyright 2013 jQuery Foundation, Inc. and other contributors
* Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: 2014-04-18
* Date: 2014-12-16
*/
(function( window ) {
......@@ -582,7 +586,7 @@ var i,
contains,
// Instance-specific data
expando = "sizzle" + -(new Date()),
expando = "sizzle" + 1 * new Date(),
preferredDoc = window.document,
dirruns = 0,
done = 0,
......@@ -597,7 +601,6 @@ var i,
},
// General-purpose constants
strundefined = typeof undefined,
MAX_NEGATIVE = 1 << 31,
// Instance methods
......@@ -607,12 +610,13 @@ var i,
push_native = arr.push,
push = arr.push,
slice = arr.slice,
// Use a stripped-down indexOf if we can't use a native one
indexOf = arr.indexOf || function( elem ) {
// Use a stripped-down indexOf as it's faster than native
// http://jsperf.com/thor-indexof-vs-for/5
indexOf = function( list, elem ) {
var i = 0,
len = this.length;
len = list.length;
for ( ; i < len; i++ ) {
if ( this[i] === elem ) {
if ( list[i] === elem ) {
return i;
}
}
......@@ -652,6 +656,7 @@ var i,
")\\)|)",
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
rwhitespace = new RegExp( whitespace + "+", "g" ),
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
......@@ -703,6 +708,14 @@ var i,
String.fromCharCode( high + 0x10000 ) :
// Supplemental Plane codepoint (surrogate pair)
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
},
// Used for iframes
// See setDocument()
// Removing the function wrapper causes a "Permission Denied"
// error in IE
unloadHandler = function() {
setDocument();
};
// Optimize for push.apply( _, NodeList )
......@@ -745,19 +758,18 @@ function Sizzle( selector, context, results, seed ) {
context = context || document;
results = results || [];
nodeType = context.nodeType;
if ( !selector || typeof selector !== "string" ) {
return results;
}
if ( typeof selector !== "string" || !selector ||
nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
return [];
return results;
}
if ( documentIsHTML && !seed ) {
if ( !seed && documentIsHTML ) {
// Shortcuts
if ( (match = rquickExpr.exec( selector )) ) {
// Try to shortcut find operations when possible (e.g., not under DocumentFragment)
if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
// Speed-up: Sizzle("#ID")
if ( (m = match[1]) ) {
if ( nodeType === 9 ) {
......@@ -789,7 +801,7 @@ function Sizzle( selector, context, results, seed ) {
return results;
// Speed-up: Sizzle(".CLASS")
} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
} else if ( (m = match[3]) && support.getElementsByClassName ) {
push.apply( results, context.getElementsByClassName( m ) );
return results;
}
......@@ -799,7 +811,7 @@ function Sizzle( selector, context, results, seed ) {
if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
nid = old = expando;
newContext = context;
newSelector = nodeType === 9 && selector;
newSelector = nodeType !== 1 && selector;
// qSA works strangely on Element-rooted queries
// We can work around this by specifying an extra ID on the root
......@@ -986,7 +998,7 @@ function createPositionalPseudo( fn ) {
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
*/
function testContext( context ) {
return context && typeof context.getElementsByTagName !== strundefined && context;
return context && typeof context.getElementsByTagName !== "undefined" && context;
}
// Expose support vars for convenience
......@@ -1010,9 +1022,8 @@ isXML = Sizzle.isXML = function( elem ) {
* @returns {Object} Returns the current document
*/
setDocument = Sizzle.setDocument = function( node ) {
var hasCompare,
doc = node ? node.ownerDocument || node : preferredDoc,
parent = doc.defaultView;
var hasCompare, parent,
doc = node ? node.ownerDocument || node : preferredDoc;
// If no document and documentElement is available, return
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
......@@ -1022,9 +1033,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// Set our document
document = doc;
docElem = doc.documentElement;
// Support tests
documentIsHTML = !isXML( doc );
parent = doc.defaultView;
// Support: IE>8
// If iframe document is assigned to "document" variable and if iframe has been reloaded,
......@@ -1033,21 +1042,22 @@ setDocument = Sizzle.setDocument = function( node ) {
if ( parent && parent !== parent.top ) {
// IE11 does not have attachEvent, so all must suffer
if ( parent.addEventListener ) {
parent.addEventListener( "unload", function() {
setDocument();
}, false );
parent.addEventListener( "unload", unloadHandler, false );
} else if ( parent.attachEvent ) {
parent.attachEvent( "onunload", function() {
setDocument();
});
parent.attachEvent( "onunload", unloadHandler );
}
}
/* Support tests
---------------------------------------------------------------------- */
documentIsHTML = !isXML( doc );
/* Attributes
---------------------------------------------------------------------- */
// Support: IE<8
// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
// Verify that getAttribute really returns attributes and not properties
// (excepting IE8 booleans)
support.attributes = assert(function( div ) {
div.className = "i";
return !div.getAttribute("className");
......@@ -1062,17 +1072,8 @@ setDocument = Sizzle.setDocument = function( node ) {
return !div.getElementsByTagName("*").length;
});
// Check if getElementsByClassName can be trusted
support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
div.innerHTML = "<div class='a'></div><div class='a i'></div>";
// Support: Safari<4
// Catch class over-caching
div.firstChild.className = "i";
// Support: Opera<10
// Catch gEBCN failure to find non-leading classes
return div.getElementsByClassName("i").length === 2;
});
// Support: IE<9
support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
// Support: IE<10
// Check if getElementById returns elements by name
......@@ -1086,7 +1087,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// ID find and filter
if ( support.getById ) {
Expr.find["ID"] = function( id, context ) {
if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
var m = context.getElementById( id );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
......@@ -1107,7 +1108,7 @@ setDocument = Sizzle.setDocument = function( node ) {
Expr.filter["ID"] = function( id ) {
var attrId = id.replace( runescape, funescape );
return function( elem ) {
var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
return node && node.value === attrId;
};
};
......@@ -1116,14 +1117,20 @@ setDocument = Sizzle.setDocument = function( node ) {
// Tag
Expr.find["TAG"] = support.getElementsByTagName ?
function( tag, context ) {
if ( typeof context.getElementsByTagName !== strundefined ) {
if ( typeof context.getElementsByTagName !== "undefined" ) {
return context.getElementsByTagName( tag );
// DocumentFragment nodes don't have gEBTN
} else if ( support.qsa ) {
return context.querySelectorAll( tag );
}
} :
function( tag, context ) {
var elem,
tmp = [],
i = 0,
// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
results = context.getElementsByTagName( tag );
// Filter out possible comments
......@@ -1141,7 +1148,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// Class
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
if ( documentIsHTML ) {
return context.getElementsByClassName( className );
}
};
......@@ -1170,13 +1177,15 @@ setDocument = Sizzle.setDocument = function( node ) {
// setting a boolean content attribute,
// since its presence should be enough
// http://bugs.jquery.com/ticket/12359
div.innerHTML = "<select msallowclip=''><option selected=''></option></select>";
docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
"<select id='" + expando + "-\f]' msallowcapture=''>" +
"<option selected=''></option></select>";
// Support: IE8, Opera 11-12.16
// Nothing should be selected when empty strings follow ^= or $= or *=
// The test attribute must be unknown in Opera but "safe" for WinRT
// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
if ( div.querySelectorAll("[msallowclip^='']").length ) {
if ( div.querySelectorAll("[msallowcapture^='']").length ) {
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
}
......@@ -1186,12 +1195,24 @@ setDocument = Sizzle.setDocument = function( node ) {
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
}
// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
rbuggyQSA.push("~=");
}
// Webkit/Opera - :checked should return selected option elements
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
// IE8 throws error here and will not see later tests
if ( !div.querySelectorAll(":checked").length ) {
rbuggyQSA.push(":checked");
}
// Support: Safari 8+, iOS 8+
// https://bugs.webkit.org/show_bug.cgi?id=136851
// In-page `selector#id sibing-combinator selector` fails
if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
rbuggyQSA.push(".#.+[+~]");
}
});
assert(function( div ) {
......@@ -1308,7 +1329,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// Maintain original order
return sortInput ?
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
0;
}
......@@ -1335,7 +1356,7 @@ setDocument = Sizzle.setDocument = function( node ) {
aup ? -1 :
bup ? 1 :
sortInput ?
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
0;
// If the nodes are siblings, we can do a quick check
......@@ -1398,7 +1419,7 @@ Sizzle.matchesSelector = function( elem, expr ) {
elem.document && elem.document.nodeType !== 11 ) {
return ret;
}
} catch(e) {}
} catch (e) {}
}
return Sizzle( expr, document, null, [ elem ] ).length > 0;
......@@ -1617,7 +1638,7 @@ Expr = Sizzle.selectors = {
return pattern ||
(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
classCache( className, function( elem ) {
return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
});
},
......@@ -1639,7 +1660,7 @@ Expr = Sizzle.selectors = {
operator === "^=" ? check && result.indexOf( check ) === 0 :
operator === "*=" ? check && result.indexOf( check ) > -1 :
operator === "$=" ? check && result.slice( -check.length ) === check :
operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
false;
};
......@@ -1759,7 +1780,7 @@ Expr = Sizzle.selectors = {
matched = fn( seed, argument ),
i = matched.length;
while ( i-- ) {
idx = indexOf.call( seed, matched[i] );
idx = indexOf( seed, matched[i] );
seed[ idx ] = !( matches[ idx ] = matched[i] );
}
}) :
......@@ -1798,6 +1819,8 @@ Expr = Sizzle.selectors = {
function( elem, context, xml ) {
input[0] = elem;
matcher( input, null, xml, results );
// Don't keep the element (issue #299)
input[0] = null;
return !results.pop();
};
}),
......@@ -1809,6 +1832,7 @@ Expr = Sizzle.selectors = {
}),
"contains": markFunction(function( text ) {
text = text.replace( runescape, funescape );
return function( elem ) {
return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
};
......@@ -2230,7 +2254,7 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS
i = matcherOut.length;
while ( i-- ) {
if ( (elem = matcherOut[i]) &&
(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
seed[temp] = !(results[temp] = elem);
}
......@@ -2265,13 +2289,16 @@ function matcherFromTokens( tokens ) {
return elem === checkContext;
}, implicitRelative, true ),
matchAnyContext = addCombinator( function( elem ) {
return indexOf.call( checkContext, elem ) > -1;
return indexOf( checkContext, elem ) > -1;
}, implicitRelative, true ),
matchers = [ function( elem, context, xml ) {
return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
(checkContext = context).nodeType ?
matchContext( elem, context, xml ) :
matchAnyContext( elem, context, xml ) );
// Avoid hanging onto element (issue #299)
checkContext = null;
return ret;
} ];
for ( ; i < len; i++ ) {
......@@ -2521,7 +2548,7 @@ select = Sizzle.select = function( selector, context, results, seed ) {
// Sort stability
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
// Support: Chrome<14
// Support: Chrome 14-35+
// Always assume duplicates if they aren't passed to the comparison function
support.detectDuplicates = !!hasDuplicate;
......@@ -2730,7 +2757,7 @@ var rootjQuery,
if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context;
// scripts is true for back-compat
// Option to run scripts is true for back-compat
// Intentionally let the error be thrown if parseHTML is not present
jQuery.merge( this, jQuery.parseHTML(
match[1],
......@@ -2758,8 +2785,8 @@ var rootjQuery,
} else {
elem = document.getElementById( match[2] );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
// Support: Blackberry 4.6
// gEBID returns nodes no longer in the document (#6963)
if ( elem && elem.parentNode ) {
// Inject the element directly into the jQuery object
this.length = 1;
......@@ -2812,7 +2839,7 @@ rootjQuery = jQuery( document );
var rparentsprev = /^(?:parents|prev(?:Until|All))/,
// methods guaranteed to produce a unique set when starting from a unique set
// Methods guaranteed to produce a unique set when starting from a unique set
guaranteedUnique = {
children: true,
contents: true,
......@@ -2892,8 +2919,7 @@ jQuery.fn.extend({
return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
},
// Determine the position of an element within
// the matched set of elements
// Determine the position of an element within the set
index: function( elem ) {
// No argument, return index in parent
......@@ -2901,7 +2927,7 @@ jQuery.fn.extend({
return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
}
// index in selector
// Index in selector
if ( typeof elem === "string" ) {
return indexOf.call( jQuery( elem ), this[ 0 ] );
}
......@@ -3317,7 +3343,7 @@ jQuery.extend({
progressValues, progressContexts, resolveContexts;
// add listeners to Deferred subordinates; treat others as resolved
// Add listeners to Deferred subordinates; treat others as resolved
if ( length > 1 ) {
progressValues = new Array( length );
progressContexts = new Array( length );
......@@ -3334,7 +3360,7 @@ jQuery.extend({
}
}
// if we're not waiting on anything, resolve the master
// If we're not waiting on anything, resolve the master
if ( !remaining ) {
deferred.resolveWith( resolveContexts, resolveValues );
}
......@@ -3413,7 +3439,7 @@ jQuery.ready.promise = function( obj ) {
readyList = jQuery.Deferred();
// Catch cases where $(document).ready() is called after the browser event has already occurred.
// we once tried to use readyState "interactive" here, but it caused issues like the one
// We once tried to use readyState "interactive" here, but it caused issues like the one
// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
......@@ -3507,7 +3533,7 @@ jQuery.acceptData = function( owner ) {
function Data() {
// Support: Android < 4,
// Support: Android<4,
// Old WebKit does not have Object.preventExtensions/freeze method,
// return new empty object instead with no [[set]] accessor
Object.defineProperty( this.cache = {}, 0, {
......@@ -3516,7 +3542,7 @@ function Data() {
}
});
this.expando = jQuery.expando + Math.random();
this.expando = jQuery.expando + Data.uid++;
}
Data.uid = 1;
......@@ -3544,7 +3570,7 @@ Data.prototype = {
descriptor[ this.expando ] = { value: unlock };
Object.defineProperties( owner, descriptor );
// Support: Android < 4
// Support: Android<4
// Fallback to a less secure definition
} catch ( e ) {
descriptor[ this.expando ] = unlock;
......@@ -3684,17 +3710,16 @@ var data_user = new Data();
/*
Implementation Summary
1. Enforce API surface and semantic compatibility with 1.9.x branch
2. Improve the module's maintainability by reducing the storage
paths to a single mechanism.
3. Use the same single mechanism to support "private" and "user" data.
4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
5. Avoid exposing implementation details on user objects (eg. expando properties)
6. Provide a clear path for implementation upgrade to WeakMap in 2014
*/
// Implementation Summary
//
// 1. Enforce API surface and semantic compatibility with 1.9.x branch
// 2. Improve the module's maintainability by reducing the storage
// paths to a single mechanism.
// 3. Use the same single mechanism to support "private" and "user" data.
// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
// 5. Avoid exposing implementation details on user objects (eg. expando properties)
// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
rmultiDash = /([A-Z])/g;
......@@ -3899,7 +3924,7 @@ jQuery.extend({
queue.unshift( "inprogress" );
}
// clear up the last queue stop function
// Clear up the last queue stop function
delete hooks.stop;
fn.call( elem, next, hooks );
}
......@@ -3909,7 +3934,7 @@ jQuery.extend({
}
},
// not intended for public consumption - generates a queueHooks object, or returns the current one
// Not public - generate a queueHooks object, or return the current one
_queueHooks: function( elem, type ) {
var key = type + "queueHooks";
return data_priv.get( elem, key ) || data_priv.access( elem, key, {
......@@ -3939,7 +3964,7 @@ jQuery.fn.extend({
this.each(function() {
var queue = jQuery.queue( this, type, data );
// ensure a hooks for this queue
// Ensure a hooks for this queue
jQuery._queueHooks( this, type );
if ( type === "fx" && queue[0] !== "inprogress" ) {
......@@ -4006,21 +4031,22 @@ var rcheckableType = (/^(?:checkbox|radio)$/i);
div = fragment.appendChild( document.createElement( "div" ) ),
input = document.createElement( "input" );
// #11217 - WebKit loses check when the name is after the checked attribute
// Support: Safari<=5.1
// Check state lost if the name is set (#11217)
// Support: Windows Web Apps (WWA)
// `name` and `type` need .setAttribute for WWA
// `name` and `type` must use .setAttribute for WWA (#14901)
input.setAttribute( "type", "radio" );
input.setAttribute( "checked", "checked" );
input.setAttribute( "name", "t" );
div.appendChild( input );
// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
// old WebKit doesn't clone checked state correctly in fragments
// Support: Safari<=5.1, Android<4.2
// Older WebKit doesn't clone checked state correctly in fragments
support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
// Support: IE<=11+
// Make sure textarea (and checkbox) defaultValue is properly cloned
// Support: IE9-IE11+
div.innerHTML = "<textarea>x</textarea>";
support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
})();
......@@ -4398,8 +4424,8 @@ jQuery.event = {
j = 0;
while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
// Triggered event must either 1) have no namespace, or
// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
// Triggered event must either 1) have no namespace, or 2) have namespace(s)
// a subset or equal to those in the bound event (both can have no namespace).
if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
event.handleObj = handleObj;
......@@ -4549,7 +4575,7 @@ jQuery.event = {
event.target = document;
}
// Support: Safari 6.0+, Chrome < 28
// Support: Safari 6.0+, Chrome<28
// Target should not be a text node (#504, #13143)
if ( event.target.nodeType === 3 ) {
event.target = event.target.parentNode;
......@@ -4654,7 +4680,7 @@ jQuery.Event = function( src, props ) {
// by a handler lower down the tree; reflect the correct value.
this.isDefaultPrevented = src.defaultPrevented ||
src.defaultPrevented === undefined &&
// Support: Android < 4.0
// Support: Android<4.0
src.returnValue === false ?
returnTrue :
returnFalse;
......@@ -4744,8 +4770,8 @@ jQuery.each({
};
});
// Create "bubbling" focus and blur events
// Support: Firefox, Chrome, Safari
// Create "bubbling" focus and blur events
if ( !support.focusinBubbles ) {
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
......@@ -4898,7 +4924,7 @@ var
// We have to close these tags to support XHTML (#13200)
wrapMap = {
// Support: IE 9
// Support: IE9
option: [ 1, "<select multiple='multiple'>", "</select>" ],
thead: [ 1, "<table>", "</table>" ],
......@@ -4909,7 +4935,7 @@ var
_default: [ 0, "", "" ]
};
// Support: IE 9
// Support: IE9
wrapMap.optgroup = wrapMap.option;
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
......@@ -4999,7 +5025,7 @@ function getAll( context, tag ) {
ret;
}
// Support: IE >= 9
// Fix IE bugs, see support tests
function fixInput( src, dest ) {
var nodeName = dest.nodeName.toLowerCase();
......@@ -5019,8 +5045,7 @@ jQuery.extend({
clone = elem.cloneNode( true ),
inPage = jQuery.contains( elem.ownerDocument, elem );
// Support: IE >= 9
// Fix Cloning issues
// Fix IE cloning issues
if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
!jQuery.isXMLDoc( elem ) ) {
......@@ -5071,8 +5096,8 @@ jQuery.extend({
// Add nodes directly
if ( jQuery.type( elem ) === "object" ) {
// Support: QtWebKit
// jQuery.merge because push.apply(_, arraylike) throws
// Support: QtWebKit, PhantomJS
// push.apply(_, arraylike) throws on ancient WebKit
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
// Convert non-html into a text node
......@@ -5094,15 +5119,14 @@ jQuery.extend({
tmp = tmp.lastChild;
}
// Support: QtWebKit
// jQuery.merge because push.apply(_, arraylike) throws
// Support: QtWebKit, PhantomJS
// push.apply(_, arraylike) throws on ancient WebKit
jQuery.merge( nodes, tmp.childNodes );
// Remember the top-level container
tmp = fragment.firstChild;
// Fixes #12346
// Support: Webkit, IE
// Ensure the created nodes are orphaned (#12392)
tmp.textContent = "";
}
}
......@@ -5464,7 +5488,7 @@ function actualDisplay( name, doc ) {
// getDefaultComputedStyle might be reliably used only on attached element
display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
// Use of this method is a temporary fix (more like optmization) until something better comes along,
// Use of this method is a temporary fix (more like optimization) until something better comes along,
// since it was removed from specification and supported only in FF
style.display : jQuery.css( elem[ 0 ], "display" );
......@@ -5514,7 +5538,14 @@ var rmargin = (/^margin/);
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
var getStyles = function( elem ) {
// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
// IE throws on elements created in popups
// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
if ( elem.ownerDocument.defaultView.opener ) {
return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
}
return window.getComputedStyle( elem, null );
};
......@@ -5526,7 +5557,7 @@ function curCSS( elem, name, computed ) {
computed = computed || getStyles( elem );
// Support: IE9
// getPropertyValue is only needed for .css('filter') in IE9, see #12537
// getPropertyValue is only needed for .css('filter') (#12537)
if ( computed ) {
ret = computed.getPropertyValue( name ) || computed[ name ];
}
......@@ -5572,15 +5603,13 @@ function addGetHookIf( conditionFn, hookFn ) {
return {
get: function() {
if ( conditionFn() ) {
// Hook not needed (or it's not possible to use it due to missing dependency),
// remove it.
// Since there are no other hooks for marginRight, remove the whole object.
// Hook not needed (or it's not possible to use it due
// to missing dependency), remove it.
delete this.get;
return;
}
// Hook needed; redefine it so that the support test is not executed again.
return (this.get = hookFn).apply( this, arguments );
}
};
......@@ -5597,6 +5626,8 @@ function addGetHookIf( conditionFn, hookFn ) {
return;
}
// Support: IE9-11+
// Style of cloned element affects source element cloned (#8908)
div.style.backgroundClip = "content-box";
div.cloneNode( true ).style.backgroundClip = "";
support.clearCloneStyle = div.style.backgroundClip === "content-box";
......@@ -5629,6 +5660,7 @@ function addGetHookIf( conditionFn, hookFn ) {
if ( window.getComputedStyle ) {
jQuery.extend( support, {
pixelPosition: function() {
// This test is executed only once but we still do memoizing
// since we can use the boxSizingReliable pre-computing.
// No need to check if the test was already performed, though.
......@@ -5642,6 +5674,7 @@ function addGetHookIf( conditionFn, hookFn ) {
return boxSizingReliableVal;
},
reliableMarginRight: function() {
// Support: Android 2.3
// Check if div with explicit width and no margin-right incorrectly
// gets computed margin-right based on width of container. (#3333)
......@@ -5663,6 +5696,7 @@ function addGetHookIf( conditionFn, hookFn ) {
ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );
docElem.removeChild( container );
div.removeChild( marginDiv );
return ret;
}
......@@ -5694,8 +5728,8 @@ jQuery.swap = function( elem, options, callback, args ) {
var
// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
// Swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
......@@ -5708,15 +5742,15 @@ var
cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
// return a css property mapped to a potentially vendor prefixed property
// Return a css property mapped to a potentially vendor prefixed property
function vendorPropName( style, name ) {
// shortcut for names that are not vendor prefixed
// Shortcut for names that are not vendor prefixed
if ( name in style ) {
return name;
}
// check for vendor prefixed names
// Check for vendor prefixed names
var capName = name[0].toUpperCase() + name.slice(1),
origName = name,
i = cssPrefixes.length;
......@@ -5749,7 +5783,7 @@ function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
val = 0;
for ( ; i < 4; i += 2 ) {
// both box models exclude margin, so add it if we want it
// Both box models exclude margin, so add it if we want it
if ( extra === "margin" ) {
val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
}
......@@ -5760,15 +5794,15 @@ function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
}
// at this point, extra isn't border nor margin, so remove border
// At this point, extra isn't border nor margin, so remove border
if ( extra !== "margin" ) {
val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
}
} else {
// at this point, extra isn't content, so add padding
// At this point, extra isn't content, so add padding
val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
// at this point, extra isn't content nor padding, so add border
// At this point, extra isn't content nor padding, so add border
if ( extra !== "padding" ) {
val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
}
......@@ -5786,7 +5820,7 @@ function getWidthOrHeight( elem, name, extra ) {
styles = getStyles( elem ),
isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
// some non-html elements return undefined for offsetWidth, so check for null/undefined
// Some non-html elements return undefined for offsetWidth, so check for null/undefined
// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
if ( val <= 0 || val == null ) {
......@@ -5801,7 +5835,7 @@ function getWidthOrHeight( elem, name, extra ) {
return val;
}
// we need the check for style in case a browser which returns unreliable values
// Check for style in case a browser which returns unreliable values
// for getComputedStyle silently falls back to the reliable elem.style
valueIsBorderBox = isBorderBox &&
( support.boxSizingReliable() || val === elem.style[ name ] );
......@@ -5810,7 +5844,7 @@ function getWidthOrHeight( elem, name, extra ) {
val = parseFloat( val ) || 0;
}
// use the active box-sizing model to add/subtract irrelevant styles
// Use the active box-sizing model to add/subtract irrelevant styles
return ( val +
augmentWidthOrHeight(
elem,
......@@ -5874,12 +5908,14 @@ function showHide( elements, show ) {
}
jQuery.extend({
// Add in style property hooks for overriding the default
// behavior of getting and setting a style property
cssHooks: {
opacity: {
get: function( elem, computed ) {
if ( computed ) {
// We should always get a number back from opacity
var ret = curCSS( elem, "opacity" );
return ret === "" ? "1" : ret;
......@@ -5907,12 +5943,12 @@ jQuery.extend({
// Add in properties whose names you wish to fix before
// setting or getting the value
cssProps: {
// normalize float css property
"float": "cssFloat"
},
// Get and set the style property on a DOM Node
style: function( elem, name, value, extra ) {
// Don't set styles on text and comment nodes
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
return;
......@@ -5925,33 +5961,32 @@ jQuery.extend({
name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
// gets hook for the prefixed version
// followed by the unprefixed version
// Gets hook for the prefixed version, then unprefixed version
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
// Check if we're setting a value
if ( value !== undefined ) {
type = typeof value;
// convert relative number strings (+= or -=) to relative numbers. #7345
// Convert "+=" or "-=" to relative numbers (#7345)
if ( type === "string" && (ret = rrelNum.exec( value )) ) {
value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
// Fixes bug #9237
type = "number";
}
// Make sure that null and NaN values aren't set. See: #7116
// Make sure that null and NaN values aren't set (#7116)
if ( value == null || value !== value ) {
return;
}
// If a number was passed in, add 'px' to the (except for certain CSS properties)
// If a number, add 'px' to the (except for certain CSS properties)
if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
value += "px";
}
// Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
// but it would mean to define eight (for every problematic property) identical functions
// Support: IE9-11+
// background-* props affect original clone's values
if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
style[ name ] = "inherit";
}
......@@ -5979,8 +6014,7 @@ jQuery.extend({
// Make sure that we're working with the right name
name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
// gets hook for the prefixed version
// followed by the unprefixed version
// Try prefixed name followed by the unprefixed name
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
// If a hook was provided get the computed value from there
......@@ -5993,12 +6027,12 @@ jQuery.extend({
val = curCSS( elem, name, styles );
}
//convert "normal" to computed value
// Convert "normal" to computed value
if ( val === "normal" && name in cssNormalTransform ) {
val = cssNormalTransform[ name ];
}
// Return, converting to number if forced or a qualifier was provided and val looks numeric
// Make numeric if forced or a qualifier was provided and val looks numeric
if ( extra === "" || extra ) {
num = parseFloat( val );
return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
......@@ -6011,8 +6045,9 @@ jQuery.each([ "height", "width" ], function( i, name ) {
jQuery.cssHooks[ name ] = {
get: function( elem, computed, extra ) {
if ( computed ) {
// certain elements can have dimension info if we invisibly show them
// however, it must have a current display style that would benefit from this
// Certain elements can have dimension info if we invisibly show them
// but it must have a current display style that would benefit
return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
jQuery.swap( elem, cssShow, function() {
return getWidthOrHeight( elem, name, extra );
......@@ -6040,8 +6075,6 @@ jQuery.each([ "height", "width" ], function( i, name ) {
jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
function( elem, computed ) {
if ( computed ) {
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
// Work around by temporarily setting element display to inline-block
return jQuery.swap( elem, { "display": "inline-block" },
curCSS, [ elem, "marginRight" ] );
}
......@@ -6059,7 +6092,7 @@ jQuery.each({
var i = 0,
expanded = {},
// assumes a single number if not a string
// Assumes a single number if not a string
parts = typeof value === "string" ? value.split(" ") : [ value ];
for ( ; i < 4; i++ ) {
......@@ -6182,17 +6215,18 @@ Tween.propHooks = {
return tween.elem[ tween.prop ];
}
// passing an empty string as a 3rd parameter to .css will automatically
// attempt a parseFloat and fallback to a string if the parse fails
// so, simple values such as "10px" are parsed to Float.
// complex values such as "rotate(1rad)" are returned as is.
// Passing an empty string as a 3rd parameter to .css will automatically
// attempt a parseFloat and fallback to a string if the parse fails.
// Simple values such as "10px" are parsed to Float;
// complex values such as "rotate(1rad)" are returned as-is.
result = jQuery.css( tween.elem, tween.prop, "" );
// Empty strings, null, undefined and "auto" are converted to 0.
return !result || result === "auto" ? 0 : result;
},
set: function( tween ) {
// use step hook for back compat - use cssHook if its there - use .style if its
// available and use plain properties where available
// Use step hook for back compat.
// Use cssHook if its there.
// Use .style if available and use plain properties where available.
if ( jQuery.fx.step[ tween.prop ] ) {
jQuery.fx.step[ tween.prop ]( tween );
} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
......@@ -6206,7 +6240,6 @@ Tween.propHooks = {
// Support: IE9
// Panic based approach to setting things on disconnected nodes
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
set: function( tween ) {
if ( tween.elem.nodeType && tween.elem.parentNode ) {
......@@ -6262,16 +6295,16 @@ var
start = +target || 1;
do {
// If previous iteration zeroed out, double until we get *something*
// Use a string for doubling factor so we don't accidentally see scale as unchanged below
// If previous iteration zeroed out, double until we get *something*.
// Use string for doubling so we don't accidentally see scale as unchanged below
scale = scale || ".5";
// Adjust and apply
start = start / scale;
jQuery.style( tween.elem, prop, start + unit );
// Update scale, tolerating zero or NaN from tween.cur()
// And breaking the loop if scale is unchanged or perfect, or if we've just had enough
// Update scale, tolerating zero or NaN from tween.cur(),
// break the loop if scale is unchanged or perfect, or if we've just had enough
} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
}
......@@ -6303,8 +6336,8 @@ function genFx( type, includeWidth ) {
i = 0,
attrs = { height: type };
// if we include width, step value is 1 to do all cssExpand values,
// if we don't include width, step value is 2 to skip over Left and Right
// If we include width, step value is 1 to do all cssExpand values,
// otherwise step value is 2 to skip over Left and Right
includeWidth = includeWidth ? 1 : 0;
for ( ; i < 4 ; i += 2 - includeWidth ) {
which = cssExpand[ i ];
......@@ -6326,7 +6359,7 @@ function createTween( value, prop, animation ) {
for ( ; index < length; index++ ) {
if ( (tween = collection[ index ].call( animation, prop, value )) ) {
// we're done with this property
// We're done with this property
return tween;
}
}
......@@ -6341,7 +6374,7 @@ function defaultPrefilter( elem, props, opts ) {
hidden = elem.nodeType && isHidden( elem ),
dataShow = data_priv.get( elem, "fxshow" );
// handle queue: false promises
// Handle queue: false promises
if ( !opts.queue ) {
hooks = jQuery._queueHooks( elem, "fx" );
if ( hooks.unqueued == null ) {
......@@ -6356,8 +6389,7 @@ function defaultPrefilter( elem, props, opts ) {
hooks.unqueued++;
anim.always(function() {
// doing this makes sure that the complete handler will be called
// before this completes
// Ensure the complete handler is called before this completes
anim.always(function() {
hooks.unqueued--;
if ( !jQuery.queue( elem, "fx" ).length ) {
......@@ -6367,7 +6399,7 @@ function defaultPrefilter( elem, props, opts ) {
});
}
// height/width overflow pass
// Height/width overflow pass
if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
// Make sure that nothing sneaks out
// Record all 3 overflow attributes because IE9-10 do not
......@@ -6429,7 +6461,7 @@ function defaultPrefilter( elem, props, opts ) {
dataShow = data_priv.access( elem, "fxshow", {} );
}
// store state if its toggle - enables .stop().toggle() to "reverse"
// Store state if its toggle - enables .stop().toggle() to "reverse"
if ( toggle ) {
dataShow.hidden = !hidden;
}
......@@ -6489,8 +6521,8 @@ function propFilter( props, specialEasing ) {
value = hooks.expand( value );
delete props[ name ];
// not quite $.extend, this wont overwrite keys already present.
// also - reusing 'index' from above because we have the correct "name"
// Not quite $.extend, this won't overwrite existing keys.
// Reusing 'index' because we have the correct "name"
for ( index in value ) {
if ( !( index in props ) ) {
props[ index ] = value[ index ];
......@@ -6509,7 +6541,7 @@ function Animation( elem, properties, options ) {
index = 0,
length = animationPrefilters.length,
deferred = jQuery.Deferred().always( function() {
// don't match elem in the :animated selector
// Don't match elem in the :animated selector
delete tick.elem;
}),
tick = function() {
......@@ -6518,7 +6550,8 @@ function Animation( elem, properties, options ) {
}
var currentTime = fxNow || createFxNow(),
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
// Support: Android 2.3
// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
temp = remaining / animation.duration || 0,
percent = 1 - temp,
index = 0,
......@@ -6554,7 +6587,7 @@ function Animation( elem, properties, options ) {
},
stop: function( gotoEnd ) {
var index = 0,
// if we are going to the end, we want to run all the tweens
// If we are going to the end, we want to run all the tweens
// otherwise we skip this part
length = gotoEnd ? animation.tweens.length : 0;
if ( stopped ) {
......@@ -6565,8 +6598,7 @@ function Animation( elem, properties, options ) {
animation.tweens[ index ].run( 1 );
}
// resolve when we played the last frame
// otherwise, reject
// Resolve when we played the last frame; otherwise, reject
if ( gotoEnd ) {
deferred.resolveWith( elem, [ animation, gotoEnd ] );
} else {
......@@ -6648,7 +6680,7 @@ jQuery.speed = function( speed, easing, fn ) {
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
// normalize opt.queue - true/undefined/null -> "fx"
// Normalize opt.queue - true/undefined/null -> "fx"
if ( opt.queue == null || opt.queue === true ) {
opt.queue = "fx";
}
......@@ -6672,10 +6704,10 @@ jQuery.speed = function( speed, easing, fn ) {
jQuery.fn.extend({
fadeTo: function( speed, to, easing, callback ) {
// show any hidden elements after setting opacity to 0
// Show any hidden elements after setting opacity to 0
return this.filter( isHidden ).css( "opacity", 0 ).show()
// animate to the value specified
// Animate to the value specified
.end().animate({ opacity: to }, speed, easing, callback );
},
animate: function( prop, speed, easing, callback ) {
......@@ -6738,9 +6770,9 @@ jQuery.fn.extend({
}
}
// start the next in the queue if the last step wasn't forced
// timers currently will call their complete callbacks, which will dequeue
// but only if they were gotoEnd
// Start the next in the queue if the last step wasn't forced.
// Timers currently will call their complete callbacks, which
// will dequeue but only if they were gotoEnd.
if ( dequeue || !gotoEnd ) {
jQuery.dequeue( this, type );
}
......@@ -6758,17 +6790,17 @@ jQuery.fn.extend({
timers = jQuery.timers,
length = queue ? queue.length : 0;
// enable finishing flag on private data
// Enable finishing flag on private data
data.finish = true;
// empty the queue first
// Empty the queue first
jQuery.queue( this, type, [] );
if ( hooks && hooks.stop ) {
hooks.stop.call( this, true );
}
// look for any active animations, and finish them
// Look for any active animations, and finish them
for ( index = timers.length; index--; ) {
if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
timers[ index ].anim.stop( true );
......@@ -6776,14 +6808,14 @@ jQuery.fn.extend({
}
}
// look for any animations in the old queue and finish them
// Look for any animations in the old queue and finish them
for ( index = 0; index < length; index++ ) {
if ( queue[ index ] && queue[ index ].finish ) {
queue[ index ].finish.call( this );
}
}
// turn off finishing flag
// Turn off finishing flag
delete data.finish;
});
}
......@@ -6886,21 +6918,21 @@ jQuery.fn.delay = function( time, type ) {
input.type = "checkbox";
// Support: iOS 5.1, Android 4.x, Android 2.3
// Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere)
// Support: iOS<=5.1, Android<=4.2+
// Default value for a checkbox should be "on"
support.checkOn = input.value !== "";
// Must access the parent to make an option select properly
// Support: IE9, IE10
// Support: IE<=11+
// Must access selectedIndex to make default options select
support.optSelected = opt.selected;
// Make sure that the options inside disabled selects aren't marked as disabled
// (WebKit marks them as disabled)
// Support: Android<=2.3
// Options inside disabled selects are incorrectly marked as disabled
select.disabled = true;
support.optDisabled = !opt.disabled;
// Check if an input maintains its value after becoming a radio
// Support: IE9, IE10
// Support: IE<=11+
// An input loses its value after becoming a radio
input = document.createElement( "input" );
input.value = "t";
input.type = "radio";
......@@ -6997,8 +7029,6 @@ jQuery.extend({
set: function( elem, value ) {
if ( !support.radioValue && value === "radio" &&
jQuery.nodeName( elem, "input" ) ) {
// Setting the type on a radio button after the value resets the value in IE6-9
// Reset value to default in case type is set after value during creation
var val = elem.value;
elem.setAttribute( "type", value );
if ( val ) {
......@@ -7068,7 +7098,7 @@ jQuery.extend({
var ret, hooks, notxml,
nType = elem.nodeType;
// don't get/set properties on text, comment and attribute nodes
// Don't get/set properties on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return;
}
......@@ -7104,8 +7134,6 @@ jQuery.extend({
}
});
// Support: IE9+
// Selectedness for an option in an optgroup can be inaccurate
if ( !support.optSelected ) {
jQuery.propHooks.selected = {
get: function( elem ) {
......@@ -7213,7 +7241,7 @@ jQuery.fn.extend({
}
}
// only assign if different to avoid unneeded rendering.
// Only assign if different to avoid unneeded rendering.
finalValue = value ? jQuery.trim( cur ) : "";
if ( elem.className !== finalValue ) {
elem.className = finalValue;
......@@ -7240,14 +7268,14 @@ jQuery.fn.extend({
return this.each(function() {
if ( type === "string" ) {
// toggle individual class names
// Toggle individual class names
var className,
i = 0,
self = jQuery( this ),
classNames = value.match( rnotwhite ) || [];
while ( (className = classNames[ i++ ]) ) {
// check each className given, space separated list
// Check each className given, space separated list
if ( self.hasClass( className ) ) {
self.removeClass( className );
} else {
......@@ -7262,7 +7290,7 @@ jQuery.fn.extend({
data_priv.set( this, "__className__", this.className );
}
// If the element has a class name or if we're passed "false",
// If the element has a class name or if we're passed `false`,
// then remove the whole classname (if there was one, the above saved it).
// Otherwise bring back whatever was previously saved (if anything),
// falling back to the empty string if nothing was stored.
......@@ -7306,9 +7334,9 @@ jQuery.fn.extend({
ret = elem.value;
return typeof ret === "string" ?
// handle most common string cases
// Handle most common string cases
ret.replace(rreturn, "") :
// handle cases where value is null/undef or number
// Handle cases where value is null/undef or number
ret == null ? "" : ret;
}
......@@ -7416,7 +7444,7 @@ jQuery.extend({
}
}
// force browsers to behave consistently when non-matching value is set
// Force browsers to behave consistently when non-matching value is set
if ( !optionSet ) {
elem.selectedIndex = -1;
}
......@@ -7437,8 +7465,6 @@ jQuery.each([ "radio", "checkbox" ], function() {
};
if ( !support.checkOn ) {
jQuery.valHooks[ this ].get = function( elem ) {
// Support: Webkit
// "" is returned instead of "on" if a value isn't specified
return elem.getAttribute("value") === null ? "on" : elem.value;
};
}
......@@ -7520,10 +7546,6 @@ jQuery.parseXML = function( data ) {
var
// Document location
ajaxLocParts,
ajaxLocation,
rhash = /#.*$/,
rts = /([?&])_=[^&]*/,
rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
......@@ -7552,22 +7574,13 @@ var
transports = {},
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
allTypes = "*/".concat("*");
allTypes = "*/".concat( "*" ),
// #8138, IE may throw an exception when accessing
// a field from window.location if document.domain has been set
try {
ajaxLocation = location.href;
} catch( e ) {
// Use the href attribute of an A element
// since IE will modify it given document.location
ajaxLocation = document.createElement( "a" );
ajaxLocation.href = "";
ajaxLocation = ajaxLocation.href;
}
// Document location
ajaxLocation = window.location.href,
// Segment location into parts
ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
// Segment location into parts
ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
function addToPrefiltersOrTransports( structure ) {
......@@ -8046,7 +8059,8 @@ jQuery.extend({
}
// We can fire global events as of now if asked to
fireGlobals = s.global;
// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
fireGlobals = jQuery.event && s.global;
// Watch for a new set of requests
if ( fireGlobals && jQuery.active++ === 0 ) {
......@@ -8119,7 +8133,7 @@ jQuery.extend({
return jqXHR.abort();
}
// aborting is no longer a cancellation
// Aborting is no longer a cancellation
strAbort = "abort";
// Install callbacks on deferreds
......@@ -8231,8 +8245,7 @@ jQuery.extend({
isSuccess = !error;
}
} else {
// We extract error from statusText
// then normalize statusText and status for non-aborts
// Extract error from statusText and normalize for non-aborts
error = statusText;
if ( status || !statusText ) {
statusText = "error";
......@@ -8288,7 +8301,7 @@ jQuery.extend({
jQuery.each( [ "get", "post" ], function( i, method ) {
jQuery[ method ] = function( url, data, callback, type ) {
// shift arguments if data argument was omitted
// Shift arguments if data argument was omitted
if ( jQuery.isFunction( data ) ) {
type = type || callback;
callback = data;
......@@ -8305,13 +8318,6 @@ jQuery.each( [ "get", "post" ], function( i, method ) {
};
});
// Attach a bunch of functions for handling common AJAX events
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
jQuery.fn[ type ] = function( fn ) {
return this.on( type, fn );
};
});
jQuery._evalUrl = function( url ) {
return jQuery.ajax({
......@@ -8529,8 +8535,9 @@ var xhrId = 0,
// Support: IE9
// Open requests must be manually aborted on unload (#5280)
if ( window.ActiveXObject ) {
jQuery( window ).on( "unload", function() {
// See https://support.microsoft.com/kb/2856746 for more info
if ( window.attachEvent ) {
window.attachEvent( "onunload", function() {
for ( var key in xhrCallbacks ) {
xhrCallbacks[ key ]();
}
......@@ -8883,6 +8890,16 @@ jQuery.fn.load = function( url, params, callback ) {
// Attach a bunch of functions for handling common AJAX events
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
jQuery.fn[ type ] = function( fn ) {
return this.on( type, fn );
};
});
jQuery.expr.filters.animated = function( elem ) {
return jQuery.grep(jQuery.timers, function( fn ) {
return elem === fn.elem;
......@@ -8919,7 +8936,8 @@ jQuery.offset = {
calculatePosition = ( position === "absolute" || position === "fixed" ) &&
( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
// Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
// Need to be able to calculate position if either
// top or left is auto and position is either absolute or fixed
if ( calculatePosition ) {
curPosition = curElem.position();
curTop = curPosition.top;
......@@ -8976,8 +8994,8 @@ jQuery.fn.extend({
return box;
}
// Support: BlackBerry 5, iOS 3 (original iPhone)
// If we don't have gBCR, just use 0,0 rather than error
// BlackBerry 5, iOS 3 (original iPhone)
if ( typeof elem.getBoundingClientRect !== strundefined ) {
box = elem.getBoundingClientRect();
}
......@@ -8999,7 +9017,7 @@ jQuery.fn.extend({
// Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
if ( jQuery.css( elem, "position" ) === "fixed" ) {
// We assume that getBoundingClientRect is available when computed position is fixed
// Assume getBoundingClientRect is there when computed position is fixed
offset = elem.getBoundingClientRect();
} else {
......@@ -9062,16 +9080,18 @@ jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function(
};
});
// Support: Safari<7+, Chrome<37+
// Add the top/left cssHooks using jQuery.fn.position
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
// getComputedStyle returns percent when specified for top/left/bottom/right
// rather than make the css module depend on the offset module, we just check for it here
// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
// getComputedStyle returns percent when specified for top/left/bottom/right;
// rather than make the css module depend on the offset module, just check for it here
jQuery.each( [ "top", "left" ], function( i, prop ) {
jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
function( elem, computed ) {
if ( computed ) {
computed = curCSS( elem, prop );
// if curCSS returns percentage, fallback to offset
// If curCSS returns percentage, fallback to offset
return rnumnonpx.test( computed ) ?
jQuery( elem ).position()[ prop ] + "px" :
computed;
......@@ -9084,7 +9104,7 @@ jQuery.each( [ "top", "left" ], function( i, prop ) {
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
// margin is only for outerHeight, outerWidth
// Margin is only for outerHeight, outerWidth
jQuery.fn[ funcName ] = function( margin, value ) {
var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
......@@ -9175,8 +9195,8 @@ jQuery.noConflict = function( deep ) {
return jQuery;
};
// Expose jQuery and $ identifiers, even in
// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
// Expose jQuery and $ identifiers, even in AMD
// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
// and CommonJS for browser emulators (#13566)
if ( typeof noGlobal === strundefined ) {
window.jQuery = window.$ = jQuery;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "paper-ripple",
"version": "1.0.4",
"license": "http://polymer.github.io/LICENSE.txt",
"description": "Adds a material design ripple to any container",
"private": true,
"authors": [
"The Polymer Authors"
],
"keywords": [
"web-components",
"polymer",
"ripple"
],
"repository": {
"type": "git",
"url": "git://github.com/PolymerElements/paper-ripple.git"
},
"main": "paper-ripple.html",
"dependencies": {
"core-icon": "Polymer/core-icon#^0.4.0",
"core-icons": "Polymer/core-icons#^0.4.0",
"font-roboto": "Polymer/font-roboto#^0.4.0"
"polymer": "Polymer/polymer#^1.1.0",
"iron-a11y-keys-behavior": "polymerelements/iron-a11y-keys-behavior#^1.0.0"
},
"devDependencies": {
"polymer-test-tools": "Polymer/polymer-test-tools"
"iron-component-page": "polymerelements/iron-component-page#^1.0.0",
"iron-icon": "polymerelements/iron-icon#^1.0.0",
"iron-icons": "polymerelements/iron-icons#^1.0.0",
"paper-styles": "polymerelements/paper-styles#^1.0.0",
"test-fixture": "polymerelements/test-fixture#^1.0.0",
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
"iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0"
},
"homepage": "https://github.com/Polymer/paper-ripple",
"version": "0.4.1",
"_release": "0.4.1",
"homepage": "https://github.com/PolymerElements/paper-ripple",
"_release": "1.0.4",
"_resolution": {
"type": "version",
"tag": "0.4.1",
"commit": "1a6458e7495c8f640651a5c42019f51eeb458e29"
"tag": "v1.0.4",
"commit": "5f5893ca7bd6a8413d2f777c092a1a179b6bd45e"
},
"_source": "git://github.com/Polymer/paper-ripple.git",
"_target": "^0.4.0",
"_originalSource": "Polymer/paper-ripple"
"_source": "git://github.com/PolymerElements/paper-ripple.git",
"_target": "^1.0.0",
"_originalSource": "PolymerElements/paper-ripple"
}
\ No newline at end of file
paper-ripple
============
See the [component page](http://www.polymer-project.org/docs/elements/paper-elements.html#paper-ripple) for more information.
`paper-ripple` provides a visual effect that other paper elements can
use to simulate a rippling effect emanating from the point of contact. The
effect can be visualized as a concentric circle with motion.
Example:
```html
<paper-ripple></paper-ripple>
```
`paper-ripple` listens to "mousedown" and "mouseup" events so it would display ripple
effect when touches on it. You can also defeat the default behavior and
manually route the down and up actions to the ripple element. Note that it is
important if you call downAction() you will have to make sure to call
upAction() so that `paper-ripple` would end the animation loop.
Example:
```html
<paper-ripple id="ripple" style="pointer-events: none;"></paper-ripple>
...
<script>
downAction: function(e) {
this.$.ripple.downAction({x: e.x, y: e.y});
},
upAction: function(e) {
this.$.ripple.upAction();
}
</script>
```
Styling ripple effect:
Use CSS color property to style the ripple:
```css
paper-ripple {
color: #4285f4;
}
```
Note that CSS color property is inherited so it is not required to set it on
the `paper-ripple` element directly.
By default, the ripple is centered on the point of contact. Apply the ``recenters`` attribute to have the ripple grow toward the center of its container.
```html
<paper-ripple recenters></paper-ripple>
```
Apply `center` to center the ripple inside its container from the start.
```html
<paper-ripple center></paper-ripple>
```
Apply `circle` class to make the rippling effect within a circle.
```html
<paper-ripple class="circle"></paper-ripple>
```
{
"name": "paper-ripple",
"version": "1.0.4",
"license": "http://polymer.github.io/LICENSE.txt",
"description": "Adds a material design ripple to any container",
"private": true,
"authors": [
"The Polymer Authors"
],
"keywords": [
"web-components",
"polymer",
"ripple"
],
"repository": {
"type": "git",
"url": "git://github.com/PolymerElements/paper-ripple.git"
},
"main": "paper-ripple.html",
"dependencies": {
"core-icon": "Polymer/core-icon#^0.4.0",
"core-icons": "Polymer/core-icons#^0.4.0",
"font-roboto": "Polymer/font-roboto#^0.4.0"
"polymer": "Polymer/polymer#^1.1.0",
"iron-a11y-keys-behavior": "polymerelements/iron-a11y-keys-behavior#^1.0.0"
},
"devDependencies": {
"polymer-test-tools": "Polymer/polymer-test-tools"
"iron-component-page": "polymerelements/iron-component-page#^1.0.0",
"iron-icon": "polymerelements/iron-icon#^1.0.0",
"iron-icons": "polymerelements/iron-icons#^1.0.0",
"paper-styles": "polymerelements/paper-styles#^1.0.0",
"test-fixture": "polymerelements/test-fixture#^1.0.0",
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
"iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0"
}
}
<!--
@license
Copyright (c) 2014 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
-->
<!doctype html>
<html>
<head>
<title>paper-ripple</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<script src="../platform/platform.js"></script>
<link rel="import" href="../core-icons/core-icons.html">
<link rel="import" href="paper-ripple.html">
<link rel="import" href="../font-roboto/roboto.html">
<link rel="import" href="../core-icon/core-icon.html">
<style shim-shadowdom>
body {
background-color: #f9f9f9;
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-touch-callout: none;
}
section {
padding: 30px 25px;
}
section > * {
margin: 10px
}
/* Button */
.button {
display: inline-block;
position: relative;
width: 120px;
height: 32px;
line-height: 32px;
border-radius: 2px;
font-size: 0.9em;
background-color: #fff;
color: #646464;
}
.button > paper-ripple {
border-radius: 2px;
overflow: hidden;
}
.button.narrow {
width: 60px;
}
.button.grey {
background-color: #eee;
}
.button.blue {
background-color: #4285f4;
color: #fff;
}
.button.green {
background-color: #0f9d58;
color: #fff;
}
.button.raised {
transition: box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1);
transition-delay: 0.2s;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
}
.button.raised:active {
box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2);
transition-delay: 0s;
}
/* Icon Button */
.icon-button {
position: relative;
display: inline-block;
width: 56px;
height: 56px;
}
.icon-button > core-icon {
margin: 16px;
transition: -webkit-transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
.icon-button:hover > core-icon {
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
.icon-button > paper-ripple {
overflow: hidden;
color: #646464;
}
.icon-button.red > core-icon::shadow path {
fill: #db4437;
}
.icon-button.red > paper-ripple {
color: #db4437;
}
.icon-button.blue > core-icon::shadow path {
fill: #4285f4;
}
.icon-button.blue > paper-ripple {
color: #4285f4;
}
/* FAB */
.fab {
position: relative;
display: inline-block;
width: 56px;
height: 56px;
border-radius: 50%;
color: #fff;
overflow: hidden;
transition: box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1);
transition-delay: 0.2s;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
}
.fab.red {
background-color: #d23f31;
}
.fab.blue {
background-color: #4285f4;
}
.fab.green {
background-color: #0f9d58;
}
.fab:active {
box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2);
transition-delay: 0s;
}
.fab > core-icon {
margin: 16px;
}
.fab > core-icon::shadow path {
fill: #fff;
}
/* Menu */
.menu {
display: inline-block;
width: 180px;
background-color: #fff;
box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2);
}
.item {
position: relative;
height: 48px;
line-height: 48px;
color: #646464;
font-size: 0.9em;
}
.menu.blue > .item {
color: #4285f4;
}
/* Card, Dialog */
.card, .dialog {
position: relative;
display: inline-block;
width: 300px;
height: 240px;
vertical-align: top;
background-color: #fff;
box-shadow: 0 12px 15px 0 rgba(0, 0, 0, 0.24);
}
.dialog {
box-sizing: border-box;
padding: 16px;
}
.dialog > .content {
height: 170px;
font-size: 0.9em;
}
.dialog > .content > .title {
font-size: 1.3em;
}
.dialog > .button {
width: 90px;
float: right;
}
.card.image {
background: url(http://lorempixel.com/300/240/nature/);
color: #fff;
}
/* Misc */
.center {
text-align: center;
}
.label {
padding: 0 16px;
}
.label-blue {
color: #4285f4;
}
.label-red {
color: #d23f31;
}
</style>
</head>
<body unresolved>
<section>
<div class="button raised">
<div class="center" fit>SUBMIT</div>
<paper-ripple fit></paper-ripple>
</div>
<div class="button raised grey">
<div class="center" fit>CANCEL</div>
<paper-ripple fit></paper-ripple>
</div>
<div class="button raised blue">
<div class="center" fit>COMPOSE</div>
<paper-ripple fit></paper-ripple>
</div>
<div class="button raised green">
<div class="center" fit>OK</div>
<paper-ripple fit></paper-ripple>
</div>
</section>
<section>
<div class="button raised grey narrow">
<div class="center" fit>+1</div>
<paper-ripple fit></paper-ripple>
</div>
<div class="button raised grey narrow label-blue">
<div class="center" fit>+1</div>
<paper-ripple fit></paper-ripple>
</div>
<div class="button raised grey narrow label-red">
<div class="center" fit>+1</div>
<paper-ripple fit></paper-ripple>
</div>
</section>
<section>
<div class="icon-button">
<core-icon icon="menu"></core-icon>
<paper-ripple class="circle recenteringTouch" fit></paper-ripple>
</div>
<div class="icon-button">
<core-icon icon="more-vert"></core-icon>
<paper-ripple class="circle recenteringTouch" fit></paper-ripple>
</div>
<div class="icon-button red">
<core-icon icon="delete"></core-icon>
<paper-ripple class="circle recenteringTouch" fit></paper-ripple>
</div>
<div class="icon-button blue">
<core-icon icon="account-box"></core-icon>
<paper-ripple class="circle recenteringTouch" fit></paper-ripple>
</div>
</section>
<section>
<div class="fab red">
<core-icon icon="add"></core-icon>
<paper-ripple class="circle recenteringTouch" fit></paper-ripple>
</div>
<div class="fab blue">
<core-icon icon="mail"></core-icon>
<paper-ripple class="circle recenteringTouch" fit></paper-ripple>
</div>
<div class="fab green">
<core-icon icon="create"></core-icon>
<paper-ripple class="circle recenteringTouch" fit></paper-ripple>
</div>
</section>
<section>
<div class="menu">
<div class="item">
<div class="label" fit>Mark as unread</div>
<paper-ripple fit></paper-ripple>
</div>
<div class="item">
<div class="label" fit>Mark as important</div>
<paper-ripple fit></paper-ripple>
</div>
<div class="item">
<div class="label" fit>Add to Tasks</div>
<paper-ripple fit></paper-ripple>
</div>
<div class="item">
<div class="label" fit>Create event</div>
<paper-ripple fit></paper-ripple>
</div>
</div>
<div class="menu blue">
<div class="item">
<div class="label" fit>Import</div>
<paper-ripple fit></paper-ripple>
</div>
<div class="item">
<div class="label" fit>Export</div>
<paper-ripple fit></paper-ripple>
</div>
<div class="item">
<div class="label" fit>Print</div>
<paper-ripple fit></paper-ripple>
</div>
<div class="item">
<div class="label" fit>Restore contacts</div>
<paper-ripple fit></paper-ripple>
</div>
</div>
</section>
<section>
<div class="dialog">
<div class="content">
<div class="title">Permission</div><br>
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.</div>
</div>
<div class="button label-blue">
<div class="center" fit>ACCEPT</div>
<paper-ripple fit></paper-ripple>
</div>
<div class="button">
<div class="center" fit>DECLINE</div>
<paper-ripple fit></paper-ripple>
</div>
</div>
<div class="card">
<paper-ripple class="recenteringTouch" fit></paper-ripple>
</div>
<div class="card image">
<paper-ripple class="recenteringTouch" fit></paper-ripple>
</div>
</section>
</body>
</html>
<!doctype html>
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
@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
The complete set of authors may be found at http://polymer.github.io/AUTHORS
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
......@@ -10,13 +11,17 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<html>
<head>
<script src="../platform/platform.js"></script>
<link rel="import" href="../core-component-page/core-component-page.html">
<title>paper-ripple</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<script src="../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../iron-component-page/iron-component-page.html">
</head>
<body unresolved>
<body>
<core-component-page></core-component-page>
<iron-component-page></iron-component-page>
</body>
</html>
<!--
@license
Copyright (c) 2014 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
-->
<x-meta id="paper-ripple" label="Ripple" group="Paper">
<template>
<paper-ripple style="width: 300px; height: 300px;"></paper-ripple>
</template>
<template id="imports">
<link rel="import" href="paper-ripple.html">
</template>
</x-meta>
......@@ -7,20 +7,30 @@ Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
<!--
Material design: [Surface reaction](https://www.google.com/design/spec/animation/responsive-interaction.html#responsive-interaction-surface-reaction)
`paper-ripple` provides a visual effect that other paper elements can
use to simulate a rippling effect emanating from the point of contact. The
effect can be visualized as a concentric circle with motion.
Example:
<div style="position:relative">
<paper-ripple></paper-ripple>
</div>
`paper-ripple` listens to "down" and "up" events so it would display ripple
Note, it's important that the parent container of the ripple be relative position, otherwise
the ripple will emanate outside of the desired container.
`paper-ripple` listens to "mousedown" and "mouseup" events so it would display ripple
effect when touches on it. You can also defeat the default behavior and
manually route the down and up actions to the ripple element. Note that it is
important if you call downAction() you will have to make sure to call upAction()
so that `paper-ripple` would end the animation loop.
important if you call `downAction()` you will have to make sure to call
`upAction()` so that `paper-ripple` would end the animation loop.
Example:
......@@ -44,9 +54,14 @@ Styling ripple effect:
Note that CSS color property is inherited so it is not required to set it on
the `paper-ripple` element directly.
Apply `recenteringTouch` class to make the recentering rippling effect.
By default, the ripple is centered on the point of contact. Apply the `recenters`
attribute to have the ripple grow toward the center of its container.
<paper-ripple recenters></paper-ripple>
You can also center the ripple inside its container from the start.
<paper-ripple class="recenteringTouch"></paper-ripple>
<paper-ripple center></paper-ripple>
Apply `circle` class to make the rippling effect within a circle.
......@@ -54,26 +69,60 @@ Apply `circle` class to make the rippling effect within a circle.
@group Paper Elements
@element paper-ripple
@homepage github.io
@hero hero.svg
@demo demo/index.html
-->
<link rel="import" href="../polymer/polymer.html" >
<dom-module id="paper-ripple">
<polymer-element name="paper-ripple" attributes="initialOpacity opacityDecayVelocity">
<template>
<!--
Fired when the animation finishes. This is useful if you want to wait until the ripple
animation finishes to perform some action.
<style>
@event transitionend
@param {Object} detail
@param {Object} detail.node The animated node
-->
<template>
<style>
:host {
display: block;
position: relative;
position: absolute;
border-radius: inherit;
overflow: hidden;
top: 0;
left: 0;
right: 0;
bottom: 0;
/* See PolymerElements/paper-behaviors/issues/34. On non-Chrome browsers,
* creating a node (with a position:absolute) in the middle of an event
* handler "interrupts" that event handler (which happens when the
* ripple is created on demand) */
pointer-events: none;
}
:host([animating]) {
/* This resolves a rendering issue in Chrome (as of 40) where the
ripple is not properly clipped by its parent (which may have
rounded corners). See: http://jsbin.com/temexa/4
Note: We only apply this style conditionally. Otherwise, the browser
will create a new compositing layer for every ripple element on the
page, and that would be bad. */
-webkit-transform: translate(0, 0);
transform: translate3d(0, 0, 0);
}
:host-context([noink]) {
:host([noink]) {
pointer-events: none;
}
#bg, #waves, .wave-container, .wave {
#background,
#waves,
.wave-container,
.wave {
pointer-events: none;
position: absolute;
top: 0;
......@@ -82,19 +131,22 @@ Apply `circle` class to make the rippling effect within a circle.
height: 100%;
}
#bg, .wave {
#background,
.wave {
opacity: 0;
}
#waves, .wave {
#waves,
.wave {
overflow: hidden;
}
.wave-container, .wave {
.wave-container,
.wave {
border-radius: 50%;
}
:host(.circle) #bg,
:host(.circle) #background,
:host(.circle) #waves {
border-radius: 50%;
}
......@@ -102,175 +154,307 @@ Apply `circle` class to make the rippling effect within a circle.
:host(.circle) .wave-container {
overflow: hidden;
}
</style>
<div id="bg"></div>
<div id="waves">
</div>
</template>
<div id="background"></div>
<div id="waves"></div>
</template>
</dom-module>
<script>
(function() {
var Utility = {
distance: function(x1, y1, x2, y2) {
var xDelta = (x1 - x2);
var yDelta = (y1 - y2);
var waveMaxRadius = 150;
//
// INK EQUATIONS
//
function waveRadiusFn(touchDownMs, touchUpMs, anim) {
// Convert from ms to s.
var touchDown = touchDownMs / 1000;
var touchUp = touchUpMs / 1000;
var totalElapsed = touchDown + touchUp;
var ww = anim.width, hh = anim.height;
// use diagonal size of container to avoid floating point math sadness
var waveRadius = Math.min(Math.sqrt(ww * ww + hh * hh), waveMaxRadius) * 1.1 + 5;
var duration = 1.1 - .2 * (waveRadius / waveMaxRadius);
var tt = (totalElapsed / duration);
var size = waveRadius * (1 - Math.pow(80, -tt));
return Math.abs(size);
return Math.sqrt(xDelta * xDelta + yDelta * yDelta);
},
now: window.performance && window.performance.now ?
window.performance.now.bind(window.performance) : Date.now
};
/**
* @param {HTMLElement} element
* @constructor
*/
function ElementMetrics(element) {
this.element = element;
this.width = this.boundingRect.width;
this.height = this.boundingRect.height;
this.size = Math.max(this.width, this.height);
}
ElementMetrics.prototype = {
get boundingRect () {
return this.element.getBoundingClientRect();
},
furthestCornerDistanceFrom: function(x, y) {
var topLeft = Utility.distance(x, y, 0, 0);
var topRight = Utility.distance(x, y, this.width, 0);
var bottomLeft = Utility.distance(x, y, 0, this.height);
var bottomRight = Utility.distance(x, y, this.width, this.height);
return Math.max(topLeft, topRight, bottomLeft, bottomRight);
}
};
/**
* @param {HTMLElement} element
* @constructor
*/
function Ripple(element) {
this.element = element;
this.color = window.getComputedStyle(element).color;
function waveOpacityFn(td, tu, anim) {
// Convert from ms to s.
var touchDown = td / 1000;
var touchUp = tu / 1000;
var totalElapsed = touchDown + touchUp;
this.wave = document.createElement('div');
this.waveContainer = document.createElement('div');
this.wave.style.backgroundColor = this.color;
this.wave.classList.add('wave');
this.waveContainer.classList.add('wave-container');
Polymer.dom(this.waveContainer).appendChild(this.wave);
if (tu <= 0) { // before touch up
return anim.initialOpacity;
this.resetInteractionState();
}
return Math.max(0, anim.initialOpacity - touchUp * anim.opacityDecayVelocity);
Ripple.MAX_RADIUS = 300;
Ripple.prototype = {
get recenters() {
return this.element.recenters;
},
get center() {
return this.element.center;
},
get mouseDownElapsed() {
var elapsed;
if (!this.mouseDownStart) {
return 0;
}
function waveOuterOpacityFn(td, tu, anim) {
// Convert from ms to s.
var touchDown = td / 1000;
var touchUp = tu / 1000;
elapsed = Utility.now() - this.mouseDownStart;
if (this.mouseUpStart) {
elapsed -= this.mouseUpElapsed;
}
return elapsed;
},
get mouseUpElapsed() {
return this.mouseUpStart ?
Utility.now () - this.mouseUpStart : 0;
},
get mouseDownElapsedSeconds() {
return this.mouseDownElapsed / 1000;
},
get mouseUpElapsedSeconds() {
return this.mouseUpElapsed / 1000;
},
get mouseInteractionSeconds() {
return this.mouseDownElapsedSeconds + this.mouseUpElapsedSeconds;
},
get initialOpacity() {
return this.element.initialOpacity;
},
get opacityDecayVelocity() {
return this.element.opacityDecayVelocity;
},
get radius() {
var width2 = this.containerMetrics.width * this.containerMetrics.width;
var height2 = this.containerMetrics.height * this.containerMetrics.height;
var waveRadius = Math.min(
Math.sqrt(width2 + height2),
Ripple.MAX_RADIUS
) * 1.1 + 5;
var duration = 1.1 - 0.2 * (waveRadius / Ripple.MAX_RADIUS);
var timeNow = this.mouseInteractionSeconds / duration;
var size = waveRadius * (1 - Math.pow(80, -timeNow));
return Math.abs(size);
},
get opacity() {
if (!this.mouseUpStart) {
return this.initialOpacity;
}
return Math.max(
0,
this.initialOpacity - this.mouseUpElapsedSeconds * this.opacityDecayVelocity
);
},
get outerOpacity() {
// Linear increase in background opacity, capped at the opacity
// of the wavefront (waveOpacity).
var outerOpacity = touchDown * 0.3;
var waveOpacity = waveOpacityFn(td, tu, anim);
return Math.max(0, Math.min(outerOpacity, waveOpacity));
}
var outerOpacity = this.mouseUpElapsedSeconds * 0.3;
var waveOpacity = this.opacity;
// Determines whether the wave should be completely removed.
function waveDidFinish(wave, radius, anim) {
var waveOpacity = waveOpacityFn(wave.tDown, wave.tUp, anim);
return Math.max(
0,
Math.min(outerOpacity, waveOpacity)
);
},
// If the wave opacity is 0 and the radius exceeds the bounds
// of the element, then this is finished.
return waveOpacity < 0.01 && radius >= Math.min(wave.maxRadius, waveMaxRadius);
};
get isOpacityFullyDecayed() {
return this.opacity < 0.01 &&
this.radius >= Math.min(this.maxRadius, Ripple.MAX_RADIUS);
},
get isRestingAtMaxRadius() {
return this.opacity >= this.initialOpacity &&
this.radius >= Math.min(this.maxRadius, Ripple.MAX_RADIUS);
},
get isAnimationComplete() {
return this.mouseUpStart ?
this.isOpacityFullyDecayed : this.isRestingAtMaxRadius;
},
function waveAtMaximum(wave, radius, anim) {
var waveOpacity = waveOpacityFn(wave.tDown, wave.tUp, anim);
get translationFraction() {
return Math.min(
1,
this.radius / this.containerMetrics.size * 2 / Math.sqrt(2)
);
},
return waveOpacity >= anim.initialOpacity && radius >= Math.min(wave.maxRadius, waveMaxRadius);
get xNow() {
if (this.xEnd) {
return this.xStart + this.translationFraction * (this.xEnd - this.xStart);
}
//
// DRAWING
//
function drawRipple(ctx, x, y, radius, innerAlpha, outerAlpha) {
// Only animate opacity and transform
if (outerAlpha !== undefined) {
ctx.bg.style.opacity = outerAlpha;
return this.xStart;
},
get yNow() {
if (this.yEnd) {
return this.yStart + this.translationFraction * (this.yEnd - this.yStart);
}
ctx.wave.style.opacity = innerAlpha;
var s = radius / (ctx.containerSize / 2);
var dx = x - (ctx.containerWidth / 2);
var dy = y - (ctx.containerHeight / 2);
return this.yStart;
},
get isMouseDown() {
return this.mouseDownStart && !this.mouseUpStart;
},
resetInteractionState: function() {
this.maxRadius = 0;
this.mouseDownStart = 0;
this.mouseUpStart = 0;
this.xStart = 0;
this.yStart = 0;
this.xEnd = 0;
this.yEnd = 0;
this.slideDistance = 0;
this.containerMetrics = new ElementMetrics(this.element);
},
draw: function() {
var scale;
var translateString;
var dx;
var dy;
this.wave.style.opacity = this.opacity;
scale = this.radius / (this.containerMetrics.size / 2);
dx = this.xNow - (this.containerMetrics.width / 2);
dy = this.yNow - (this.containerMetrics.height / 2);
ctx.wc.style.webkitTransform = 'translate3d(' + dx + 'px,' + dy + 'px,0)';
ctx.wc.style.transform = 'translate3d(' + dx + 'px,' + dy + 'px,0)';
// 2d transform for safari because of border-radius and overflow:hidden clipping bug.
// https://bugs.webkit.org/show_bug.cgi?id=98538
ctx.wave.style.webkitTransform = 'scale(' + s + ',' + s + ')';
ctx.wave.style.transform = 'scale3d(' + s + ',' + s + ',1)';
}
//
// SETUP
//
function createWave(elem) {
var elementStyle = window.getComputedStyle(elem);
var fgColor = elementStyle.color;
var inner = document.createElement('div');
inner.style.backgroundColor = fgColor;
inner.classList.add('wave');
var outer = document.createElement('div');
outer.classList.add('wave-container');
outer.appendChild(inner);
var container = elem.$.waves;
container.appendChild(outer);
elem.$.bg.style.backgroundColor = fgColor;
var wave = {
bg: elem.$.bg,
wc: outer,
wave: inner,
waveColor: fgColor,
maxRadius: 0,
isMouseDown: false,
mouseDownStart: 0.0,
mouseUpStart: 0.0,
tDown: 0,
tUp: 0
};
return wave;
}
this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy + 'px)';
this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + 'px, 0)';
this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')';
this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)';
},
function removeWaveFromScope(scope, wave) {
if (scope.waves) {
var pos = scope.waves.indexOf(wave);
scope.waves.splice(pos, 1);
// FIXME cache nodes
wave.wc.remove();
}
};
/** @param {Event=} event */
downAction: function(event) {
var xCenter = this.containerMetrics.width / 2;
var yCenter = this.containerMetrics.height / 2;
this.resetInteractionState();
this.mouseDownStart = Utility.now();
if (this.center) {
this.xStart = xCenter;
this.yStart = yCenter;
this.slideDistance = Utility.distance(
this.xStart, this.yStart, this.xEnd, this.yEnd
);
} else {
this.xStart = event ?
event.detail.x - this.containerMetrics.boundingRect.left :
this.containerMetrics.width / 2;
this.yStart = event ?
event.detail.y - this.containerMetrics.boundingRect.top :
this.containerMetrics.height / 2;
}
if (this.recenters) {
this.xEnd = xCenter;
this.yEnd = yCenter;
this.slideDistance = Utility.distance(
this.xStart, this.yStart, this.xEnd, this.yEnd
);
}
this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom(
this.xStart,
this.yStart
);
this.waveContainer.style.top =
(this.containerMetrics.height - this.containerMetrics.size) / 2 + 'px';
this.waveContainer.style.left =
(this.containerMetrics.width - this.containerMetrics.size) / 2 + 'px';
this.waveContainer.style.width = this.containerMetrics.size + 'px';
this.waveContainer.style.height = this.containerMetrics.size + 'px';
},
// Shortcuts.
var pow = Math.pow;
var now = Date.now;
if (window.performance && performance.now) {
now = performance.now.bind(performance);
/** @param {Event=} event */
upAction: function(event) {
if (!this.isMouseDown) {
return;
}
function cssColorWithAlpha(cssColor, alpha) {
var parts = cssColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
if (typeof alpha == 'undefined') {
alpha = 1;
}
if (!parts) {
return 'rgba(255, 255, 255, ' + alpha + ')';
}
return 'rgba(' + parts[1] + ', ' + parts[2] + ', ' + parts[3] + ', ' + alpha + ')';
}
this.mouseUpStart = Utility.now();
},
function dist(p1, p2) {
return Math.sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2));
remove: function() {
Polymer.dom(this.waveContainer.parentNode).removeChild(
this.waveContainer
);
}
};
function distanceFromPointToFurthestCorner(point, size) {
var tl_d = dist(point, {x: 0, y: 0});
var tr_d = dist(point, {x: size.w, y: 0});
var bl_d = dist(point, {x: 0, y: size.h});
var br_d = dist(point, {x: size.w, y: size.h});
return Math.max(tl_d, tr_d, bl_d, br_d);
}
Polymer({
is: 'paper-ripple',
Polymer('paper-ripple', {
behaviors: [
Polymer.IronA11yKeysBehavior
],
properties: {
/**
* The initial opacity set on the wave.
*
......@@ -278,7 +462,10 @@ Apply `circle` class to make the rippling effect within a circle.
* @type number
* @default 0.25
*/
initialOpacity: 0.25,
initialOpacity: {
type: Number,
value: 0.25
},
/**
* How fast (opacity per second) the wave fades out.
......@@ -287,178 +474,294 @@ Apply `circle` class to make the rippling effect within a circle.
* @type number
* @default 0.8
*/
opacityDecayVelocity: 0.8,
opacityDecayVelocity: {
type: Number,
value: 0.8
},
backgroundFill: true,
pixelDensity: 2,
/**
* If true, ripples will exhibit a gravitational pull towards
* the center of their container as they fade away.
*
* @attribute recenters
* @type boolean
* @default false
*/
recenters: {
type: Boolean,
value: false
},
eventDelegates: {
down: 'downAction',
up: 'upAction'
/**
* If true, ripples will center inside its container
*
* @attribute recenters
* @type boolean
* @default false
*/
center: {
type: Boolean,
value: false
},
ready: function() {
this.waves = [];
/**
* A list of the visual ripples.
*
* @attribute ripples
* @type Array
* @default []
*/
ripples: {
type: Array,
value: function() {
return [];
}
},
downAction: function(e) {
var wave = createWave(this);
this.cancelled = false;
wave.isMouseDown = true;
wave.tDown = 0.0;
wave.tUp = 0.0;
wave.mouseUpStart = 0.0;
wave.mouseDownStart = now();
var rect = this.getBoundingClientRect();
var width = rect.width;
var height = rect.height;
var touchX = e.x - rect.left;
var touchY = e.y - rect.top;
wave.startPosition = {x:touchX, y:touchY};
if (this.classList.contains("recenteringTouch")) {
wave.endPosition = {x: width / 2, y: height / 2};
wave.slideDistance = dist(wave.startPosition, wave.endPosition);
}
wave.containerSize = Math.max(width, height);
wave.containerWidth = width;
wave.containerHeight = height;
wave.maxRadius = distanceFromPointToFurthestCorner(wave.startPosition, {w: width, h: height});
// The wave is circular so constrain its container to 1:1
wave.wc.style.top = (wave.containerHeight - wave.containerSize) / 2 + 'px';
wave.wc.style.left = (wave.containerWidth - wave.containerSize) / 2 + 'px';
wave.wc.style.width = wave.containerSize + 'px';
wave.wc.style.height = wave.containerSize + 'px';
this.waves.push(wave);
if (!this._loop) {
this._loop = this.animate.bind(this, {
width: width,
height: height
});
requestAnimationFrame(this._loop);
/**
* True when there are visible ripples animating within the
* element.
*/
animating: {
type: Boolean,
readOnly: true,
reflectToAttribute: true,
value: false
},
/**
* If true, the ripple will remain in the "down" state until `holdDown`
* is set to false again.
*/
holdDown: {
type: Boolean,
value: false,
observer: '_holdDownChanged'
},
/**
* If true, the ripple will not generate a ripple effect
* via pointer interaction.
* Calling ripple's imperative api like `simulatedRipple` will
* still generate the ripple effect.
*/
noink: {
type: Boolean,
value: false
},
_animating: {
type: Boolean
},
_boundAnimate: {
type: Function,
value: function() {
return this.animate.bind(this);
}
}
// else there is already a rAF
},
upAction: function() {
for (var i = 0; i < this.waves.length; i++) {
// Declare the next wave that has mouse down to be mouse'ed up.
var wave = this.waves[i];
if (wave.isMouseDown) {
wave.isMouseDown = false
wave.mouseUpStart = now();
wave.mouseDownStart = 0;
wave.tUp = 0.0;
break;
observers: [
'_noinkChanged(noink, isAttached)'
],
get target () {
var ownerRoot = Polymer.dom(this).getOwnerRoot();
var target;
if (this.parentNode.nodeType == 11) { // DOCUMENT_FRAGMENT_NODE
target = ownerRoot.host;
} else {
target = this.parentNode;
}
return target;
},
keyBindings: {
'enter:keydown': '_onEnterKeydown',
'space:keydown': '_onSpaceKeydown',
'space:keyup': '_onSpaceKeyup'
},
attached: function() {
this.listen(this.target, 'up', 'uiUpAction');
this.listen(this.target, 'down', 'uiDownAction');
},
detached: function() {
this.unlisten(this.target, 'up', 'uiUpAction');
this.unlisten(this.target, 'down', 'uiDownAction');
},
get shouldKeepAnimating () {
for (var index = 0; index < this.ripples.length; ++index) {
if (!this.ripples[index].isAnimationComplete) {
return true;
}
}
this._loop && requestAnimationFrame(this._loop);
return false;
},
cancel: function() {
this.cancelled = true;
simulatedRipple: function() {
this.downAction(null);
// Please see polymer/polymer#1305
this.async(function() {
this.upAction();
}, 1);
},
animate: function(ctx) {
var shouldRenderNextFrame = false;
/**
* Provokes a ripple down effect via a UI event,
* respecting the `noink` property.
* @param {Event=} event
*/
uiDownAction: function(event) {
if (!this.noink) {
this.downAction(event);
}
},
var deleteTheseWaves = [];
// The oldest wave's touch down duration
var longestTouchDownDuration = 0;
var longestTouchUpDuration = 0;
// Save the last known wave color
var lastWaveColor = null;
// wave animation values
var anim = {
initialOpacity: this.initialOpacity,
opacityDecayVelocity: this.opacityDecayVelocity,
height: ctx.height,
width: ctx.width
/**
* Provokes a ripple down effect via a UI event,
* *not* respecting the `noink` property.
* @param {Event=} event
*/
downAction: function(event) {
if (this.holdDown && this.ripples.length > 0) {
return;
}
for (var i = 0; i < this.waves.length; i++) {
var wave = this.waves[i];
var ripple = this.addRipple();
ripple.downAction(event);
if (wave.mouseDownStart > 0) {
wave.tDown = now() - wave.mouseDownStart;
if (!this._animating) {
this.animate();
}
if (wave.mouseUpStart > 0) {
wave.tUp = now() - wave.mouseUpStart;
},
/**
* Provokes a ripple up effect via a UI event,
* respecting the `noink` property.
* @param {Event=} event
*/
uiUpAction: function(event) {
if (!this.noink) {
this.upAction(event);
}
},
/**
* Provokes a ripple up effect via a UI event,
* *not* respecting the `noink` property.
* @param {Event=} event
*/
upAction: function(event) {
if (this.holdDown) {
return;
}
// Determine how long the touch has been up or down.
var tUp = wave.tUp;
var tDown = wave.tDown;
longestTouchDownDuration = Math.max(longestTouchDownDuration, tDown);
longestTouchUpDuration = Math.max(longestTouchUpDuration, tUp);
this.ripples.forEach(function(ripple) {
ripple.upAction(event);
});
// Obtain the instantenous size and alpha of the ripple.
var radius = waveRadiusFn(tDown, tUp, anim);
var waveAlpha = waveOpacityFn(tDown, tUp, anim);
var waveColor = cssColorWithAlpha(wave.waveColor, waveAlpha);
lastWaveColor = wave.waveColor;
this.animate();
},
// Position of the ripple.
var x = wave.startPosition.x;
var y = wave.startPosition.y;
onAnimationComplete: function() {
this._animating = false;
this.$.background.style.backgroundColor = null;
this.fire('transitionend');
},
// Ripple gravitational pull to the center of the canvas.
if (wave.endPosition) {
addRipple: function() {
var ripple = new Ripple(this);
// This translates from the origin to the center of the view based on the max dimension of
var translateFraction = Math.min(1, radius / wave.containerSize * 2 / Math.sqrt(2) );
Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);
this.$.background.style.backgroundColor = ripple.color;
this.ripples.push(ripple);
x += translateFraction * (wave.endPosition.x - wave.startPosition.x);
y += translateFraction * (wave.endPosition.y - wave.startPosition.y);
this._setAnimating(true);
return ripple;
},
removeRipple: function(ripple) {
var rippleIndex = this.ripples.indexOf(ripple);
if (rippleIndex < 0) {
return;
}
// If we do a background fill fade too, work out the correct color.
var bgFillColor = null;
if (this.backgroundFill) {
var bgFillAlpha = waveOuterOpacityFn(tDown, tUp, anim);
bgFillColor = cssColorWithAlpha(wave.waveColor, bgFillAlpha);
this.ripples.splice(rippleIndex, 1);
ripple.remove();
if (!this.ripples.length) {
this._setAnimating(false);
}
},
animate: function() {
var index;
var ripple;
this._animating = true;
// Draw the ripple.
drawRipple(wave, x, y, radius, waveAlpha, bgFillAlpha);
for (index = 0; index < this.ripples.length; ++index) {
ripple = this.ripples[index];
// Determine whether there is any more rendering to be done.
var maximumWave = waveAtMaximum(wave, radius, anim);
var waveDissipated = waveDidFinish(wave, radius, anim);
var shouldKeepWave = !waveDissipated || maximumWave;
var shouldRenderWaveAgain = !waveDissipated && !maximumWave;
shouldRenderNextFrame = shouldRenderNextFrame || shouldRenderWaveAgain;
if (!shouldKeepWave || this.cancelled) {
deleteTheseWaves.push(wave);
ripple.draw();
this.$.background.style.opacity = ripple.outerOpacity;
if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) {
this.removeRipple(ripple);
}
}
if (shouldRenderNextFrame) {
requestAnimationFrame(this._loop);
if (!this.shouldKeepAnimating && this.ripples.length === 0) {
this.onAnimationComplete();
} else {
window.requestAnimationFrame(this._boundAnimate);
}
},
for (var i = 0; i < deleteTheseWaves.length; ++i) {
var wave = deleteTheseWaves[i];
removeWaveFromScope(this, wave);
}
_onEnterKeydown: function() {
this.uiDownAction();
this.async(this.uiUpAction, 1);
},
_onSpaceKeydown: function() {
this.uiDownAction();
},
_onSpaceKeyup: function() {
this.uiUpAction();
},
if (!this.waves.length && this._loop) {
// clear the background color
this.$.bg.style.backgroundColor = null;
this._loop = null;
this.fire('core-transitionend');
// note: holdDown does not respect noink since it can be a focus based
// effect.
_holdDownChanged: function(newVal, oldVal) {
if (oldVal === undefined) {
return;
}
if (newVal) {
this.downAction();
} else {
this.upAction();
}
},
_noinkChanged: function(noink, attached) {
if (attached) {
this.keyEventTarget = noink ? this : this.target;
}
}
});
})();
</script>
</polymer-element>
<!--
@license
Copyright (c) 2014 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
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script>
//
// INK EQUATIONS
//
// Animation constants.
var globalSpeed = 1;
var waveOpacityDecayVelocity = 0.8 / globalSpeed; // opacity per second.
var waveInitialOpacity = 0.25;
var waveLingerOnTouchUp = 0.2;
var waveMaxRadius = 150;
// TODOs:
// - rather than max distance to corner, use hypotenuos(sp) (diag)
// - use quadratic for the fall off, move fast at the beginning,
// - on cancel, immediately fade out, reverse the direction
function waveRadiusFn(touchDownMs, touchUpMs, ww, hh) {
// Convert from ms to s.
var touchDown = touchDownMs / 1000;
var touchUp = touchUpMs / 1000;
var totalElapsed = touchDown + touchUp;
var waveRadius = Math.min(Math.max(ww, hh), waveMaxRadius) * 1.1 + 5;
var dduration = 1.1 - .2 * (waveRadius / waveMaxRadius);
var tt = (totalElapsed / dduration);
var ssize = waveRadius * (1 - Math.pow(80, -tt));
return Math.abs(ssize);
}
function waveOpacityFn(td, tu) {
// Convert from ms to s.
var touchDown = td / 1000;
var touchUp = tu / 1000;
var totalElapsed = touchDown + touchUp;
if (tu <= 0) { // before touch up
return waveInitialOpacity;
}
return Math.max(0, waveInitialOpacity - touchUp * waveOpacityDecayVelocity);
}
function waveOuterOpacityFn(td, tu) {
// Convert from ms to s.
var touchDown = td / 1000;
var touchUp = tu / 1000;
// Linear increase in background opacity, capped at the opacity
// of the wavefront (waveOpacity).
var outerOpacity = touchDown * 0.3;
var waveOpacity = waveOpacityFn(td, tu);
return Math.max(0, Math.min(outerOpacity, waveOpacity));
}
function waveGravityToCenterPercentageFn(td, tu, r) {
// Convert from ms to s.
var touchDown = td / 1000;
var touchUp = tu / 1000;
var totalElapsed = touchDown + touchUp;
return Math.min(1.0, touchUp * 6);
}
// Determines whether the wave should be completely removed.
function waveDidFinish(wave, radius) {
var waveOpacity = waveOpacityFn(wave.tDown, wave.tUp);
// Does not linger any more.
// var lingerTimeMs = waveLingerOnTouchUp * 1000;
// If the wave opacity is 0 and the radius exceeds the bounds
// of the element, then this is finished.
if (waveOpacity < 0.01 && radius >= wave.maxRadius) {
return true;
}
return false;
};
//
// DRAWING
//
function animateIcon() {
var el = document.getElementById('button_toolbar0');
el.classList.add('animate');
setTimeout(function(){
el.classList.remove('animate');
el.classList.toggle('selected');
}, 500);
}
function drawRipple(canvas, x, y, radius, innerColor, outerColor, innerColorAlpha, outerColorAlpha) {
var ctx = canvas.getContext('2d');
if (outerColor) {
ctx.fillStyle = outerColor;
ctx.fillRect(0,0,canvas.width, canvas.height);
}
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = innerColor;
ctx.fill();
}
function drawLabel(canvas, label, fontSize, color, alignment) {
var ctx = canvas.getContext('2d');
ctx.font= fontSize + 'px Helvetica';
var metrics = ctx.measureText(label);
var width = metrics.width;
var height = metrics.height;
ctx.fillStyle = color;
var xPos = (canvas.width/2 - width)/2;
if (alignment === 'left') { xPos = 16; }
ctx.fillText(label, xPos, canvas.height/2 - (canvas.height/2 - fontSize +2) / 2);
}
//
// BUTTON SETUP
//
function createWave(elem) {
var elementStyle = window.getComputedStyle(elem);
var fgColor = elementStyle.color;
var wave = {
waveColor: fgColor,
maxRadius: 0,
isMouseDown: false,
mouseDownStart: 0.0,
mouseUpStart: 0.0,
tDown: 0,
tUp: 0
};
return wave;
}
function removeWaveFromScope(scope, wave) {
if (scope.waves) {
var pos = scope.waves.indexOf(wave);
scope.waves.splice(pos, 1);
}
};
function setUpPaperByClass( classname ) {
var elems = document.querySelectorAll( classname );
[].forEach.call( elems, function( el ) {
setUpPaper(el);
});
}
function setUpPaper(elem) {
var pixelDensity = 2;
var elementStyle = window.getComputedStyle(elem);
var fgColor = elementStyle.color;
var bgColor = elementStyle.backgroundColor;
elem.width = elem.clientWidth;
elem.setAttribute('width', elem.clientWidth * pixelDensity + "px");
elem.setAttribute('height', elem.clientHeight * pixelDensity + "px");
var isButton = elem.classList.contains( 'button' ) || elem.classList.contains( 'button_floating' ) | elem.classList.contains( 'button_menu' );
var isToolbarButton = elem.classList.contains( 'button_toolbar' );
elem.getContext('2d').scale(pixelDensity, pixelDensity)
var scope = {
backgroundFill: true,
element: elem,
label: 'Button',
waves: [],
};
scope.label = elem.getAttribute('value') || elementStyle.content;
scope.labelFontSize = elementStyle.fontSize.split("px")[0];
drawLabel(elem, scope.label, scope.labelFontSize, fgColor, elem.style.textAlign);
//
// RENDER FOR EACH FRAME
//
var onFrame = function() {
var shouldRenderNextFrame = false;
// Clear the canvas
var ctx = elem.getContext('2d');
ctx.clearRect(0, 0, elem.width, elem.height);
var deleteTheseWaves = [];
// The oldest wave's touch down duration
var longestTouchDownDuration = 0;
var longestTouchUpDuration = 0;
// Save the last known wave color
var lastWaveColor = null;
for (var i = 0; i < scope.waves.length; i++) {
var wave = scope.waves[i];
if (wave.mouseDownStart > 0) {
wave.tDown = now() - wave.mouseDownStart;
}
if (wave.mouseUpStart > 0) {
wave.tUp = now() - wave.mouseUpStart;
}
// Determine how long the touch has been up or down.
var tUp = wave.tUp;
var tDown = wave.tDown;
longestTouchDownDuration = Math.max(longestTouchDownDuration, tDown);
longestTouchUpDuration = Math.max(longestTouchUpDuration, tUp);
// Obtain the instantenous size and alpha of the ripple.
var radius = waveRadiusFn(tDown, tUp, elem.width, elem.height);
var waveAlpha = waveOpacityFn(tDown, tUp);
var waveColor = cssColorWithAlpha(wave.waveColor, waveAlpha);
lastWaveColor = wave.waveColor;
// Position of the ripple.
var x = wave.startPosition.x;
var y = wave.startPosition.y;
// Ripple gravitational pull to the center of the canvas.
if (wave.endPosition) {
var translateFraction = waveGravityToCenterPercentageFn(tDown, tUp, wave.maxRadius);
// This translates from the origin to the center of the view based on the max dimension of
var translateFraction = Math.min(1, radius / wave.containerSize * 2 / Math.sqrt(2) );
x += translateFraction * (wave.endPosition.x - wave.startPosition.x);
y += translateFraction * (wave.endPosition.y - wave.startPosition.y);
}
// If we do a background fill fade too, work out the correct color.
var bgFillColor = null;
if (scope.backgroundFill) {
var bgFillAlpha = waveOuterOpacityFn(tDown, tUp);
bgFillColor = cssColorWithAlpha(wave.waveColor, bgFillAlpha);
}
// Draw the ripple.
drawRipple(elem, x, y, radius, waveColor, bgFillColor);
// Determine whether there is any more rendering to be done.
var shouldRenderWaveAgain = !waveDidFinish(wave, radius);
shouldRenderNextFrame = shouldRenderNextFrame || shouldRenderWaveAgain;
if (!shouldRenderWaveAgain) {
deleteTheseWaves.push(wave);
}
}
if (shouldRenderNextFrame) {
window.requestAnimationFrame(onFrame);
} else {
// If there is nothing to draw, clear any drawn waves now because
// we're not going to get another requestAnimationFrame any more.
var ctx = elem.getContext('2d');
ctx.clearRect(0, 0, elem.width, elem.height);
}
// Draw the label at the very last point so it is on top of everything.
drawLabel(elem, scope.label, scope.labelFontSize, fgColor, elem.style.textAlign);
for (var i = 0; i < deleteTheseWaves.length; ++i) {
var wave = deleteTheseWaves[i];
removeWaveFromScope(scope, wave);
}
};
//
// MOUSE DOWN HANDLER
//
elem.addEventListener('mousedown', function(e) {
var wave = createWave(e.target);
var elem = scope.element;
wave.isMouseDown = true;
wave.tDown = 0.0;
wave.tUp = 0.0;
wave.mouseUpStart = 0.0;
wave.mouseDownStart = now();
var width = e.target.width / 2; // Retina canvas
var height = e.target.height / 2;
var touchX = e.clientX - e.target.offsetLeft - e.target.offsetParent.offsetLeft;
var touchY = e.clientY - e.target.offsetTop - e.target.offsetParent.offsetTop;
wave.startPosition = {x:touchX, y:touchY};
if (elem.classList.contains("recenteringTouch")) {
wave.endPosition = {x: width / 2, y: height / 2};
wave.slideDistance = dist(wave.startPosition, wave.endPosition);
}
wave.containerSize = Math.max(width, height);
wave.maxRadius = distanceFromPointToFurthestCorner(wave.startPosition, {w: width, h: height});
elem.classList.add("activated");
scope.waves.push(wave);
window.requestAnimationFrame(onFrame);
return false;
});
//
// MOUSE UP HANDLER
//
elem.addEventListener('mouseup', function(e) {
elem.classList.remove("activated");
for (var i = 0; i < scope.waves.length; i++) {
// Declare the next wave that has mouse down to be mouse'ed up.
var wave = scope.waves[i];
if (wave.isMouseDown) {
wave.isMouseDown = false
wave.mouseUpStart = now();
wave.mouseDownStart = 0;
wave.tUp = 0.0;
break;
}
}
return false;
});
elem.addEventListener('mouseout', function(e) {
elem.classList.remove("activated");
for (var i = 0; i < scope.waves.length; i++) {
// Declare the next wave that has mouse down to be mouse'ed up.
var wave = scope.waves[i];
if (wave.isMouseDown) {
wave.isMouseDown = false
wave.mouseUpStart = now();
wave.mouseDownStart = 0;
wave.tUp = 0.0;
wave.cancelled = true;
break;
}
}
return false;
});
return scope;
};
// Shortcuts.
var pow = Math.pow;
var now = function() { return new Date().getTime(); };
// Quad beizer where t is between 0 and 1.
function quadBezier(t, p0, p1, p2, p3) {
return pow(1 - t, 3) * p0 +
3 * pow(1 - t, 2) * t * p1 +
(1 - t) * pow(t, 2) * p2 +
pow(t, 3) * p3;
}
function easeIn(t) {
return quadBezier(t, 0.4, 0.0, 1, 1);
}
function cssColorWithAlpha(cssColor, alpha) {
var parts = cssColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
if (typeof alpha == 'undefined') {
alpha = 1;
}
if (!parts) {
return 'rgba(255, 255, 255, ' + alpha + ')';
}
return 'rgba(' + parts[1] + ', ' + parts[2] + ', ' + parts[3] + ', ' + alpha + ')';
}
function dist(p1, p2) {
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
}
function distanceFromPointToFurthestCorner(point, size) {
var tl_d = dist(point, {x: 0, y: 0});
var tr_d = dist(point, {x: size.w, y: 0});
var bl_d = dist(point, {x: 0, y: size.h});
var br_d = dist(point, {x: size.w, y: size.h});
return Math.max(Math.max(tl_d, tr_d), Math.max(bl_d, br_d));
}
function toggleDialog() {
var el = document.getElementById('dialog');
el.classList.toggle("visible");
}
function toggleMenu() {
var el = document.getElementById('menu');
el.classList.toggle("visible");
}
// Initialize
function init() {
setUpPaperByClass( '.paper' );
}
window.addEventListener('DOMContentLoaded', init, false);
</script>
<style type="text/css" media="screen">
body {
background-color: #f9f9f9;
margin:0; padding:0;
font-family:sans-serif;
font-size:14px;
}
* {
-webkit-user-select: none;
cursor:default;
}
.toolbar {
background-color:#673AB7;
height:56px;
overflow:hidden;
}
#dialog {
width:250px;
height:120px;
opacity:0.0;
pointer-events:none;
-webkit-transform: scale(0.95) translate3d(0,100px,0);;
-webkit-transition: -webkit-transform 0.3s ease-out, height 0.2s ease-out, opacity 0.2s ease-out, -webkit-box-shadow .5s ease-out;
-webkit-box-shadow:0 10px 10px rgba(0,0,0,0.12), 0 5px 5px rgba(0,0,0,0.24);
-webkit-transition-delay:0.25s;
}
#dialog.visible {
pointer-events:all;
opacity:1.0;
-webkit-transform: scale(1.0) translate3d(0,0,0);;
width:250px;
height:160px;
-webkit-box-shadow:0 19px 19px rgba(0,0,0,0.30), 0 15px 6px rgba(0,0,0,0.22);
-webkit-transition-delay:0.0s;
}
.dialog {
top:120px;
right: 0;
left: 50%;
margin-left:-125px;
padding:24px 16px 20px 24px;
position:absolute;
background:white;
color:rgba(0,0,0,0.5);
margin-bottom:38px;
overflow:hidden;
}
.dialog h1 {
font-size:20px;
font-weight:normal;
padding:0; margin-top:0;
}
.dialog .button {
position:absolute;
top:160px;
right:10px;
}
/*#menu {
width:250px;
height:120px;
opacity:0.0;
pointer-events:none;
-webkit-transform: scale(0.95) translate3d(0,100px,0);;
-webkit-transition: -webkit-transform 0.3s ease-out, height 0.2s ease-out, opacity 0.2s ease-out, -webkit-box-shadow .5s ease-out;
-webkit-box-shadow:0 10px 10px rgba(0,0,0,0.12), 0 5px 5px rgba(0,0,0,0.24);
}
#menu.visible {
pointer-events:all;
opacity:1.0;
-webkit-transform: scale(1.0) translate3d(0,0,0);;
width:250px;
height:160px;
-webkit-box-shadow:0 19px 19px rgba(0,0,0,0.30), 0 15px 6px rgba(0,0,0,0.22);
}*/
.menu {
width:160px;
height:160px;
background:white;
position:absolute;
right:8px;
top: 8px;
padding:0;
opacity:0.0;
pointer-events:none;
-webkit-transform: scale(0.95) translate3d(0,0,0);;
-webkit-transition: -webkit-transform 0.3s ease-out, width 0.2s ease-out, height 0.3s ease-out, opacity 0.1s ease-out, -webkit-box-shadow .5s ease-out;
-webkit-box-shadow:0 10px 10px rgba(0,0,0,0.12), 0 5px 5px rgba(0,0,0,0.24);
-webkit-transition-delay:0.35s;
overflow:hidden;
}
.menu.visible {
width:180px;
height:192px;
pointer-events:all;
opacity:1.0;
-webkit-transform: scale(1.0) translate3d(0,0,0);;
-webkit-box-shadow:0 10px 10px rgba(0,0,0,0.12), 0 5px 5px rgba(0,0,0,0.24);
-webkit-transition-delay:0.15s;
}
.menu div {
height:48px;
padding:0;
}
.menu canvas {
height:48px;
width: 100%;
}
.button_floating {
width:56px;
height:56px;
color:#fff;
background-color:#039BE5;
border-radius:28px;
position:absolute;
top:388px;
right:40px;
}
.container {
}
.button {
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
}
.button_menu.container {
margin: 0px;
height: 48px;
padding: 0;
}
.button_menu {
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
text-align:left !important;
color:rgb(100,100,100);
}
.button_toolbar {
-webkit-border-radius: 84px;
color: rgb(255,255,255);
width: 80px;
height: 80px;
float:left;
margin-right:-24px;
margin-top:-12px;
background-color: rgba(0, 0, 0, 0);
}
#button_small {
color: rgb(100, 100, 100);
background-color: #ffffff;
width: 80px;
height: 32px;
}
#button_blue {
color: rgb(255, 255, 255);
background-color: #0277BD;
width: 80px;
height: 32px;
}
#button_borderless_square {
color: #ffffff;
background-color: #f9f9f9;
border: 1px solid #f0f0f0;
width: 100px;
height: 100px;
background-color: rgb(255, 255, 255, 0);
background-image:url(http://wallpaperandbackground.com/wp-content/uploads/2014/03/Field-Landscape.jpg);
background-size:cover;
}
#button_borderless {
color: #777777;
background-color: #ffffff;
width:80px;
height: 32px;
margin-right:72px;
content: "CANCEL";
}
#button_borderless_blue {
color: #4285F4;
background-color: #ffffff;
width: 64px;
height: 32px;
content:"OK";
}
#button_large {
color: rgb(255, 255, 255);
width: 100%;
height: 360px;
background-color:#81D4FA;
}
#button_toolbar1 {
content: '';
color:transparent;
margin-left:-4px;
}
#button_toolbar2 {
content: '★';
float:right;
}
#button_toolbar3 {
content: 'MENU';
font-size: 14px;
width: 88px;
height:88px;
margin-top: -16px;
color:#7FFFFF;
float:right;
margin-right:0;
}
.caption {
z-index: 100;
background-color: red;
}
#button_toolbar0.animate {
-webkit-animation: play 0.5s steps(16);
}
.button.raised {
-webkit-transition: -webkit-box-shadow 0.2s;
-webkit-transition-delay: 0.2s;
-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.12), 0 1px 1px rgba(0,0,0,0.24);
}
.button.raised.activated {
-webkit-box-shadow: 0px 10px 10px rgba(0,0,0,0.19), 0px 6px 3px rgba(0,0,0,0.23);
-webkit-transition-delay: 0.0s;
}
.floating {
-webkit-transition: -webkit-box-shadow 0.2s;
-webkit-transition-delay: 0.2s;
-webkit-box-shadow:0 3px 3px rgba(0,0,0,0.16), 0 3px 3px rgba(0,0,0,0.23);
}
.floating.activated {
-webkit-box-shadow: 0px 14px 14px rgba(0,0,0,0.25), 0px 10px 5px rgba(0,0,0,0.22);
-webkit-transition-delay: 0.0s;
}
#title {
color:white;
font-size:20px;
line-height:58px;
margin-left:24px;
}
.content {
padding-left:72px; padding-top:24px; padding-right:144px;
line-height:20px;
color:#666;
}
@-webkit-keyframes play {
from { background-position: 0px 0px; }
to { background-position: 0px -384px; }
}
#button_toolbar0 {
pointer-events: none;
position:absolute;
top:16px;
left: 24px;
content: "\00a0";
width:24px;
height:24px;
background-image: url(data:image/png;base64,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);
}
#button_toolbar0.selected {
background-image: url(data:image/png;base64,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);
}
</style>
</head>
<body id="">
<div class="toolbar">
<div id="button_toolbar0" class="toolbar_icon"></div>
<span class="container"><canvas class="paper button_toolbar recenteringTouch" id="button_toolbar1" onclick="animateIcon()"></canvas></span>
<span id="title" style="float:left">Ripple test</span>
<span class="container"><canvas onClick="toggleMenu()" class="paper button_toolbar recenteringTouch" id="button_toolbar3"></canvas></span>
<span class="container"><canvas class="paper button_toolbar recenteringTouch" id="button_toolbar2"></canvas></span>
<span class="container"><canvas class="paper button_toolbar recenteringTouch" id="button_toolbar2"></canvas></span>
</div>
<div id="dialog" class="dialog visible">
<h1>Press mah buttons!</h1> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
<span class="container"><canvas class="paper button" id="button_borderless" value="CANCEL"></canvas></span>
<span class="container"><canvas class="paper button" id="button_borderless_blue" onclick="toggleDialog()" value="OK"></canvas></span>
</div>
<div id="menu" class="menu visible">
<div class="container button_menu"><canvas class="paper button_menu" value="Fold" style="text-align:left"></canvas></div>
<div class="container button_menu"><canvas class="paper button_menu" value="Spindle" style="text-align:left"></canvas></div>
<div class="container button_menu"><canvas class="paper button_menu" onClick="" value="Mutilate" style="text-align:left"></canvas></div>
<div class="container button_menu"><canvas class="paper button_menu" onClick="toggleMenu()" value="Dismiss" style="text-align:left"></canvas></div>
</div>
<div class="container"><canvas class="paper button recenteringTouch" id="button_large"></canvas></div>
<div class="content" style="">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam. 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.
<p></p>
<span class="container" style="margin-right:8px;"><canvas class="paper button raised" id="button_blue" value="ABORT"></canvas></span>
<span class="container" style="margin-right:8px;"><canvas class="paper button raised" id="button_small" value="RETRY"></canvas></span>
<span class="container"><canvas class="paper button raised" id="button_small" value="FAIL"></canvas></span>
<p><p>
<canvas class="paper button" id="button_borderless_square"></canvas>
</div>
<div class="container"><canvas onClick="toggleDialog()" class="paper button_floating floating recenteringTouch" id="button_floating" value="★"></canvas></div>
</body>
</html>
{
"name": "paper-tabs",
"private": true,
"dependencies": {
"core-icons": "Polymer/core-icons#^0.4.0",
"core-selector": "Polymer/core-selector#^0.4.0",
"core-toolbar": "Polymer/core-toolbar#^0.4.0",
"font-roboto": "Polymer/font-roboto#^0.4.0",
"paper-icon-button": "Polymer/paper-icon-button#^0.4.0",
"paper-ripple": "Polymer/paper-ripple#^0.4.0"
},
"homepage": "https://github.com/Polymer/paper-tabs",
"version": "0.4.1",
"_release": "0.4.1",
"_resolution": {
"type": "version",
"tag": "0.4.1",
"commit": "c4ab5a81bd0c9bf96f9d24eb45b53a31910f210f"
},
"_source": "git://github.com/Polymer/paper-tabs.git",
"_target": "~0.4.0",
"_originalSource": "Polymer/paper-tabs"
}
\ No newline at end of file
paper-tabs
============
See the [component page](http://www.polymer-project.org/docs/elements/paper-elements.html#paper-tabs) for more information.
{
"name": "paper-tabs",
"version": "1.0.10",
"license": "http://polymer.github.io/LICENSE.txt",
"description": "Material design tabs",
"private": true,
"main": "paper-tabs.html",
"authors": [
"The Polymer Authors"
],
"keywords": [
"web-components",
"polymer",
"tabs",
"control"
],
"repository": {
"type": "git",
"url": "git://github.com/PolymerElements/paper-tabs.git"
},
"dependencies": {
"core-icons": "Polymer/core-icons#^0.4.0",
"core-selector": "Polymer/core-selector#^0.4.0",
"core-toolbar": "Polymer/core-toolbar#^0.4.0",
"font-roboto": "Polymer/font-roboto#^0.4.0",
"paper-icon-button": "Polymer/paper-icon-button#^0.4.0",
"paper-ripple": "Polymer/paper-ripple#^0.4.0"
"iron-behaviors": "polymerelements/iron-behaviors#^1.0.0",
"iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
"iron-icon": "polymerelements/iron-icon#^1.0.0",
"iron-iconset-svg": "polymerelements/iron-iconset-svg#^1.0.0",
"iron-menu-behavior": "polymerelements/iron-menu-behavior#^1.0.0",
"iron-resizable-behavior": "polymerelements/iron-resizable-behavior#^1.0.0",
"paper-styles": "polymerelements/paper-styles#^1.0.0",
"polymer": "Polymer/polymer#^1.0.0",
"paper-icon-button": "polymerelements/paper-icon-button#^1.0.0",
"paper-behaviors": "PolymerElements/paper-behaviors#^1.0.0"
},
"devDependencies": {
"iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
"iron-test-helpers": "polymerelements/iron-test-helpers#^1.0.0",
"paper-toolbar": "polymerelements/paper-toolbar#^1.0.0",
"test-fixture": "polymerelements/test-fixture#^1.0.0",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0",
"web-component-tester": "*",
"iron-pages": "PolymerElements/iron-pages#^1.0.0"
}
}
<!--
@license
Copyright (c) 2014 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
-->
<!doctype html>
<html>
<head>
<title>paper-tabs</title>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
<script src="../platform/platform.js"></script>
<link rel="import" href="../core-icons/core-icons.html">
<link rel="import" href="paper-tabs.html">
<link rel="import" href="../core-toolbar/core-toolbar.html">
<link rel="import" href="../paper-icon-button/paper-icon-button.html">
<link rel="import" href="../font-roboto/roboto.html">
<style shim-shadowdom>
body {
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
margin: 0;
padding: 24px;
color: #333;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-touch-callout: none;
}
paper-tabs, core-toolbar {
background-color: #00bcd4;
color: #fff;
box-shadow: 0px 3px 2px rgba(0, 0, 0, 0.2);
}
core-toolbar paper-tabs {
box-shadow: none;
}
paper-tabs[noink][nobar] paper-tab.core-selected {
color: #ffff8d;
}
paper-tabs.transparent-teal {
background-color: transparent;
color: #00bcd4;
box-shadow: none;
}
paper-tabs.transparent-teal::shadow #selectionBar {
background-color: #00bcd4;
}
paper-tabs.transparent-teal paper-tab::shadow #ink {
color: #00bcd4;
}
h3 {
font-size: 16px;
font-weight: 400;
}
</style>
</head>
<body unresolved>
<h3>A. No ink effect and no sliding bar</h3>
<paper-tabs selected="0" noink nobar>
<paper-tab>ITEM ONE</paper-tab>
<paper-tab>ITEM TWO</paper-tab>
<paper-tab>ITEM THREE</paper-tab>
</paper-tabs>
<br>
<br>
<h3>B. The bar slides to the selected tab</h3>
<paper-tabs selected="0" noink>
<paper-tab>ITEM ONE</paper-tab>
<paper-tab>ITEM TWO</paper-tab>
<paper-tab>ITEM THREE</paper-tab>
</paper-tabs>
<br>
<br>
<h3>C. Inky Tabs</h3>
<paper-tabs selected="0">
<paper-tab>ITEM ONE</paper-tab>
<paper-tab>ITEM TWO</paper-tab>
<paper-tab>ITEM THREE</paper-tab>
</paper-tabs>
<br>
<br>
<paper-tabs selected="0" class="transparent-teal">
<paper-tab>ITEM ONE</paper-tab>
<paper-tab>ITEM TWO</paper-tab>
<paper-tab>ITEM THREE</paper-tab>
</paper-tabs>
<br>
<br>
<core-toolbar class="medium-tall">
<paper-icon-button icon="menu"></paper-icon-button>
<div flex>Title</div>
<paper-icon-button icon="search"></paper-icon-button>
<paper-icon-button icon="more-vert"></paper-icon-button>
<div class="bottom fit" horizontal layout>
<paper-tabs selected="0" flex style="max-width: 600px;">
<paper-tab>ITEM ONE</paper-tab>
<paper-tab>ITEM TWO</paper-tab>
<paper-tab>ITEM THREE</paper-tab>
</paper-tabs>
</div>
</core-toolbar>
<br>
<br>
<core-toolbar class="tall">
<paper-tabs selected="0" class="bottom indent" style="width: 200px;" self-end>
<paper-tab>ITEM ONE</paper-tab>
<paper-tab>ITEM TWO</paper-tab>
</paper-tabs>
<div class="bottom" flex></div>
<paper-icon-button class="bottom" icon="search"></paper-icon-button>
</core-toolbar>
</body>
</html>
<!doctype html>
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
@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
The complete set of authors may be found at http://polymer.github.io/AUTHORS
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
......@@ -10,13 +11,15 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<html>
<head>
<script src="../platform/platform.js"></script>
<link rel="import" href="../core-component-page/core-component-page.html">
<title>paper-tabs</title>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
<script src="../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../iron-component-page/iron-component-page.html">
</head>
<body unresolved>
<body>
<core-component-page sources='["paper-tabs.html", "paper-tab.html"]'></core-component-page>
<iron-component-page sources='["paper-tabs.html", "paper-tab.html"]'></iron-component-page>
</body>
</html>
<!--
@license
Copyright (c) 2014 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
-->
<x-meta id="paper-tabs" label="Tabs" group="Paper" isContainer>
<template>
<paper-tabs selected="0" style="width: 480px; background-color: #00bcd4; color: #fff; box-shadow: 0px 3px 2px rgba(0, 0, 0, 0.2);">
<paper-tab>ITEM ONE</paper-tab>
<paper-tab>ITEM TWO</paper-tab>
<paper-tab>ITEM THREE</paper-tab>
<paper-tab>ITEM FOUR</paper-tab>
<paper-tab>ITEM FIVE</paper-tab>
</paper-tabs>
</template>
<template id="imports">
<link rel="import" href="paper-tabs.html">
</template>
</x-meta>
<x-meta id="paper-tab" label="Tab" group="Paper">
<template>
<paper-tab style="width: 120px; height: 40px;">TAB</paper-tab>
</template>
<template id="imports">
<link rel="import" href="paper-tab.html">
</template>
</x-meta>
<x-meta id="paper-tab-panel" label="Panel with Tabs" group="Paper" isContainer>
<template>
<section layout vertical style="width:420px;height:630px;border:5px solid #ccc;">
<paper-tabs selected="0" noink nobar style="background-color:#00bcd4; color:#fff;box-shadow:0px 3px 2px rgba(0, 0, 0, 0.2);">
<paper-tab>ITEM ONE</paper-tab>
<paper-tab>ITEM TWO</paper-tab>
</paper-tabs>
<section flex relative>
</section>
</section>
</template>
<template id="imports">
<link rel="import" href="paper-tabs.html">
</template>
</x-meta>
/*
Copyright (c) 2014 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
*/
:host {
display: block;
position: relative;
overflow: hidden;
}
#tabContainer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.tab-content {
transition: opacity .1s cubic-bezier(0.4, 0.0, 1, 1), color .1s cubic-bezier(0.4, 0.0, 1, 1);
cursor: default;
pointer-events: none;
}
:host(:not(.core-selected)) .tab-content {
opacity: 0.6;
}
#ink {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
color: #ffff8d;
}
:host[noink] #ink {
pointer-events: none;
}
:host-context(paper-tabs[noink]) #ink {
pointer-events: none;
}
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
@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
......@@ -7,6 +8,13 @@ Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../iron-behaviors/iron-control-state.html">
<link rel="import" href="../iron-behaviors/iron-button-state.html">
<link rel="import" href="../paper-behaviors/paper-ripple-behavior.html">
<!--
`paper-tab` is styled to look like a tab. It should be used in conjunction with
`paper-tabs`.
......@@ -19,48 +27,129 @@ Example:
<paper-tab>TAB 3</paper-tab>
</paper-tabs>
Styling tab:
### Styling
To change the ink color:
The following custom properties and mixins are available for styling:
.pink paper-tab::shadow #ink {
color: #ff4081;
}
Custom property | Description | Default
----------------|-------------|----------
`--paper-tab-ink` | Ink color | `--paper-yellow-a100`
`--paper-tab` | Mixin applied to the tab | `{}`
`--paper-tab-content` | Mixin applied to the tab content | `{}`
`--paper-tab-content-unselected` | Mixin applied to the tab content when the tab is not selected | `{}`
@group Paper Elements
@element paper-tab
@homepage github.io
-->
<link rel="import" href="../paper-ripple/paper-ripple.html">
<dom-module id="paper-tab">
<style>
:host {
@apply(--layout-inline);
@apply(--layout-center);
@apply(--layout-center-justified);
@apply(--layout-flex);
position: relative;
padding: 0 12px;
overflow: hidden;
cursor: pointer;
@apply(--paper-tab);
}
:host(:focus) {
outline: none;
}
:host([link]) {
padding: 0;
}
.tab-content {
height: 100%;
-webkit-transform: translateZ(0);
transform: translateZ(0);
transition: opacity 0.1s cubic-bezier(0.4, 0.0, 1, 1);
@apply(--paper-tab-content);
}
:host(:not(.iron-selected)) > .tab-content {
opacity: 0.8;
<polymer-element name="paper-tab" attributes="noink" role="tab">
<template>
@apply(--paper-tab-content-unselected);
}
:host(:focus) .tab-content {
opacity: 1;
font-weight: 700;
}
paper-ripple {
color: var(--paper-tab-ink, --paper-yellow-a100);
}
<link rel="stylesheet" href="paper-tab.css">
.tab-content > ::content > a {
height: 100%;
/* flex */
-ms-flex: 1 1 0.000000001px;
-webkit-flex: 1;
flex: 1;
-webkit-flex-basis: 0.000000001px;
flex-basis: 0.000000001px;
}
<div id="tabContainer" center-justified center horizontal layout>
</style>
<div class="tab-content"><content></content></div>
<paper-ripple id="ink" initialOpacity="0.95" opacityDecayVelocity="0.98"></paper-ripple>
<template>
<div class="tab-content flex-auto center-center horizontal layout">
<content></content>
</div>
</template>
</template>
</dom-module>
<script>
Polymer('paper-tab', {
Polymer({
/**
* If true, ink ripple effect is disabled.
*
* @attribute noink
* @type boolean
* @default false
*/
noink: false
is: 'paper-tab',
behaviors: [
Polymer.IronControlState,
Polymer.IronButtonState,
Polymer.PaperRippleBehavior
],
hostAttributes: {
role: 'tab'
},
listeners: {
down: '_updateNoink'
},
ready: function() {
var ripple = this.getRipple();
ripple.initialOpacity = 0.95;
ripple.opacityDecayVelocity = 0.98;
},
attached: function() {
this._updateNoink();
},
get _parentNoink () {
var parent = Polymer.dom(this).parentNode;
return !!parent && !!parent.noink;
},
_updateNoink: function() {
this.noink = !!this.noink || !!this._parentNoink;
}
});
</script>
</polymer-element>
/*
Copyright (c) 2014 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
*/
:host {
display: block;
position: relative;
font-size: 14px;
font-weight: 500;
height: 48px;
overflow: hidden;
}
#tabsContainer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
white-space: nowrap;
}
#selectionBar {
position: absolute;
height: 2px;
bottom: 0;
left: 0;
width: 0;
background-color: #ffff8d;
transition: width, left;
}
#selectionBar[hidden] {
display: hidden;
}
#selectionBar.expand {
transition-duration: 0.15s;
transition-timing-function: cubic-bezier(0.4, 0.0, 1, 1);
}
#selectionBar.contract {
transition-duration: 0.18s;
transition-timing-function: cubic-bezier(0.0, 0.0, 0.2, 1);
}
polyfill-next-selector { content: '#tabsContainer > *:not(#selectionBar)'; }
::content > * {
-ms-flex: 1;
-webkit-flex: 1;
flex: 1;
}
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
@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
......@@ -7,10 +8,22 @@ Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
<link rel="import" href="../iron-resizable-behavior/iron-resizable-behavior.html">
<link rel="import" href="../iron-menu-behavior/iron-menubar-behavior.html">
<link rel="import" href="../iron-icon/iron-icon.html">
<link rel="import" href="../paper-icon-button/paper-icon-button.html">
<link rel="import" href="../paper-styles/color.html">
<link rel="import" href="paper-tabs-icons.html">
<link rel="import" href="paper-tab.html">
<!--
`paper-tabs` is a `core-selector` styled to look like tabs. Tabs make it easy to
explore and switch between different views or functional aspects of an app, or
to browse categorized data sets.
Material design: [Tabs](https://www.google.com/design/spec/components/tabs.html)
`paper-tabs` makes it easy to explore and switch between different views or functional aspects of
an app, or to browse categorized data sets.
Use `selected` property to get or set the selected tab.
......@@ -25,101 +38,496 @@ Example:
See <a href="#paper-tab">paper-tab</a> for more information about
`paper-tab`.
Styling tabs:
A common usage for `paper-tabs` is to use it along with `iron-pages` to switch
between different views.
To change the sliding bar color:
<paper-tabs selected="{{selected}}">
<paper-tab>Tab 1</paper-tab>
<paper-tab>Tab 2</paper-tab>
<paper-tab>Tab 3</paper-tab>
</paper-tabs>
<iron-pages selected="{{selected}}">
<div>Page 1</div>
<div>Page 2</div>
<div>Page 3</div>
</iron-pages>
paper-tabs.pink::shadow #selectionBar {
background-color: #ff4081;
}
@group Paper Elements
@element paper-tabs
@extends core-selector
@homepage github.io
To use links in tabs, add `link` attribute to `paper-tab` and put an `<a>`
element in `paper-tab`.
Example:
<paper-tabs selected="0">
<paper-tab link>
<a href="#link1" class="horizontal center-center layout">TAB ONE</a>
</paper-tab>
<paper-tab link>
<a href="#link2" class="horizontal center-center layout">TAB TWO</a>
</paper-tab>
<paper-tab link>
<a href="#link3" class="horizontal center-center layout">TAB THREE</a>
</paper-tab>
</paper-tabs>
### Styling
The following custom properties and mixins are available for styling:
Custom property | Description | Default
----------------|-------------|----------
`--paper-tabs-selection-bar-color` | Color for the selection bar | `--paper-yellow-a100`
`--paper-tabs` | Mixin applied to the tabs | `{}`
@hero hero.svg
@demo demo/index.html
-->
<link rel="import" href="../core-selector/core-selector.html">
<link rel="import" href="paper-tab.html">
<dom-module id="paper-tabs">
<style>
:host {
@apply(--layout);
@apply(--layout-center);
height: 48px;
font-size: 14px;
font-weight: 500;
overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
@apply(--paper-tabs);
}
<polymer-element name="paper-tabs" extends="core-selector" attributes="noink nobar" role="tablist">
<template>
:host-context([dir=rtl]) {
@apply(--layout-horizontal-reverse);
}
#tabsContainer {
position: relative;
height: 100%;
white-space: nowrap;
overflow: hidden;
}
<link rel="stylesheet" href="paper-tabs.css">
#tabsContent {
height: 100%;
}
#tabsContent.scrollable {
position: absolute;
white-space: nowrap;
}
<div id="tabsContainer" horizontal layout>
.hidden {
display: none;
}
.not-visible {
opacity: 0;
cursor: default;
}
paper-icon-button {
width: 48px;
height: 48px;
padding: 12px;
margin: 0 4px;
}
<shadow></shadow>
<div id="selectionBar" hidden?="{{nobar}}" on-transitionend="{{barTransitionEnd}}"></div>
#selectionBar {
position: absolute;
height: 2px;
bottom: 0;
left: 0;
right: 0;
background-color: var(--paper-tabs-selection-bar-color, --paper-yellow-a100);
-webkit-transform-origin: left center;
transform-origin: left center;
-webkit-transform: scale(0);
transform: scale(0);
transition: -webkit-transform;
transition: transform;
@apply(--paper-tabs-selection-bar);
}
#selectionBar.align-bottom {
top: 0;
bottom: auto;
}
#selectionBar.expand {
transition-duration: 0.15s;
transition-timing-function: cubic-bezier(0.4, 0.0, 1, 1);
}
#selectionBar.contract {
transition-duration: 0.18s;
transition-timing-function: cubic-bezier(0.0, 0.0, 0.2, 1);
}
#tabsContent > ::content > *:not(#selectionBar) {
height: 100%;
}
</style>
<template>
<paper-icon-button icon="paper-tabs:chevron-left" class$="[[_computeScrollButtonClass(_leftHidden, scrollable, hideScrollButtons)]]" on-up="_onScrollButtonUp" on-down="_onLeftScrollButtonDown" tabindex="-1"></paper-icon-button>
<div id="tabsContainer" class="flex" on-track="_scroll" on-down="_down">
<div id="tabsContent" class$="[[_computeTabsContentClass(scrollable)]]">
<content select="*"></content>
<div id="selectionBar" class$="[[_computeSelectionBarClass(noBar, alignBottom)]]"
on-transitionend="_onBarTransitionEnd"></div>
</div>
</div>
</template>
<paper-icon-button icon="paper-tabs:chevron-right" class$="[[_computeScrollButtonClass(_rightHidden, scrollable, hideScrollButtons)]]" on-up="_onScrollButtonUp" on-down="_onRightScrollButtonDown" tabindex="-1"></paper-icon-button>
</template>
</dom-module>
<script>
Polymer('paper-tabs', {
Polymer({
is: 'paper-tabs',
behaviors: [
Polymer.IronResizableBehavior,
Polymer.IronMenubarBehavior
],
properties: {
/**
* If true, ink effect is disabled.
*
* @attribute noink
* @type boolean
* @default false
* If true, ink ripple effect is disabled. When this property is changed,
* all descendant `<paper-tab>` elements have their `noink` property
* changed to the new value as well.
*/
noink: false,
noink: {
type: Boolean,
value: false,
observer: '_noinkChanged'
},
/**
* If true, the bottom bar to indicate the selected tab will not be shown.
*
* @attribute nobar
* @type boolean
* @default false
*/
nobar: false,
noBar: {
type: Boolean,
value: false
},
activateEvent: 'down',
/**
* If true, the slide effect for the bottom bar is disabled.
*/
noSlide: {
type: Boolean,
value: false
},
nostretch: false,
/**
* If true, tabs are scrollable and the tab width is based on the label width.
*/
scrollable: {
type: Boolean,
value: false
},
/**
* If true, dragging on the tabs to scroll is disabled.
*/
disableDrag: {
type: Boolean,
value: false
},
/**
* If true, scroll buttons (left/right arrow) will be hidden for scrollable tabs.
*/
hideScrollButtons: {
type: Boolean,
value: false
},
selectedIndexChanged: function(old) {
var s = this.$.selectionBar.style;
/**
* If true, the tabs are aligned to bottom (the selection bar appears at the top).
*/
alignBottom: {
type: Boolean,
value: false
},
/**
* Gets or sets the selected element. The default is to use the index of the item.
*/
selected: {
type: String,
notify: true
},
if (!this.selectedItem) {
s.width = 0;
s.left = 0;
selectable: {
type: String,
value: 'paper-tab'
},
_step: {
type: Number,
value: 10
},
_holdDelay: {
type: Number,
value: 1
},
_leftHidden: {
type: Boolean,
value: false
},
_rightHidden: {
type: Boolean,
value: false
},
_previousTab: {
type: Object
}
},
hostAttributes: {
role: 'tablist'
},
listeners: {
'iron-resize': '_onResize',
'iron-select': '_onIronSelect',
'iron-deselect': '_onIronDeselect'
},
created: function() {
this._holdJob = null;
},
ready: function() {
this.setScrollDirection('y', this.$.tabsContainer);
},
_noinkChanged: function(noink) {
var childTabs = Polymer.dom(this).querySelectorAll('paper-tab');
childTabs.forEach(noink ? this._setNoinkAttribute : this._removeNoinkAttribute);
},
_setNoinkAttribute: function(element) {
element.setAttribute('noink', '');
},
_removeNoinkAttribute: function(element) {
element.removeAttribute('noink');
},
_computeScrollButtonClass: function(hideThisButton, scrollable, hideScrollButtons) {
if (!scrollable || hideScrollButtons) {
return 'hidden';
}
if (hideThisButton) {
return 'not-visible';
}
return '';
},
_computeTabsContentClass: function(scrollable) {
return scrollable ? 'scrollable' : 'horizontal layout';
},
_computeSelectionBarClass: function(noBar, alignBottom) {
if (noBar) {
return 'hidden';
} else if (alignBottom) {
return 'align-bottom';
}
},
// TODO(cdata): Add `track` response back in when gesture lands.
_onResize: function() {
this.debounce('_onResize', function() {
this._scroll();
this._tabChanged(this.selectedItem);
}, 10);
},
_onIronSelect: function(event) {
this._tabChanged(event.detail.item, this._previousTab);
this._previousTab = event.detail.item;
this.cancelDebouncer('tab-changed');
},
_onIronDeselect: function(event) {
this.debounce('tab-changed', function() {
this._tabChanged(null, this._previousTab);
// See polymer/polymer#1305
}, 1);
},
get _tabContainerScrollSize () {
return Math.max(
0,
this.$.tabsContainer.scrollWidth -
this.$.tabsContainer.offsetWidth
);
},
_scroll: function(e, detail) {
if (!this.scrollable) {
return;
}
var w = 100 / this.items.length;
var ddx = (detail && -detail.ddx) || 0;
this._affectScroll(ddx);
},
if (this.nostretch || old === null || old === -1) {
s.width = w + '%';
s.left = this.selectedIndex * w + '%';
_down: function(e) {
// go one beat async to defeat IronMenuBehavior
// autorefocus-on-no-selection timeout
this.async(function() {
if (this._defaultFocusAsync) {
this.cancelAsync(this._defaultFocusAsync);
this._defaultFocusAsync = null;
}
}, 1);
},
_affectScroll: function(dx) {
this.$.tabsContainer.scrollLeft += dx;
var scrollLeft = this.$.tabsContainer.scrollLeft;
this._leftHidden = scrollLeft === 0;
this._rightHidden = scrollLeft === this._tabContainerScrollSize;
},
_onLeftScrollButtonDown: function() {
this._scrollToLeft();
this._holdJob = setInterval(this._scrollToLeft.bind(this), this._holdDelay);
},
_onRightScrollButtonDown: function() {
this._scrollToRight();
this._holdJob = setInterval(this._scrollToRight.bind(this), this._holdDelay);
},
_onScrollButtonUp: function() {
clearInterval(this._holdJob);
this._holdJob = null;
},
_scrollToLeft: function() {
this._affectScroll(-this._step);
},
_scrollToRight: function() {
this._affectScroll(this._step);
},
_tabChanged: function(tab, old) {
if (!tab) {
this._positionBar(0, 0);
return;
}
var r = this.$.tabsContent.getBoundingClientRect();
var w = r.width;
var tabRect = tab.getBoundingClientRect();
var tabOffsetLeft = tabRect.left - r.left;
this._pos = {
width: this._calcPercent(tabRect.width, w),
left: this._calcPercent(tabOffsetLeft, w)
};
if (this.noSlide || old == null) {
// position bar directly without animation
this._positionBar(this._pos.width, this._pos.left);
return;
}
var oldRect = old.getBoundingClientRect();
var oldIndex = this.items.indexOf(old);
var index = this.items.indexOf(tab);
var m = 5;
// bar animation: expand
this.$.selectionBar.classList.add('expand');
if (old < this.selectedIndex) {
s.width = w + w * (this.selectedIndex - old) - m + '%';
this._transitionCounter = 1;
if (oldIndex < index) {
this._positionBar(this._calcPercent(tabRect.left + tabRect.width - oldRect.left, w) - m,
this._left);
} else {
this._positionBar(this._calcPercent(oldRect.left + oldRect.width - tabRect.left, w) - m,
this._calcPercent(tabOffsetLeft, w) + m);
}
if (this.scrollable) {
this._scrollToSelectedIfNeeded(tabRect.width, tabOffsetLeft);
}
},
_scrollToSelectedIfNeeded: function(tabWidth, tabOffsetLeft) {
var l = tabOffsetLeft - this.$.tabsContainer.scrollLeft;
if (l < 0) {
this.$.tabsContainer.scrollLeft += l;
} else {
s.width = w + w * (old - this.selectedIndex) - m + '%';
s.left = this.selectedIndex * w + m + '%';
this._transitionCounter = 2;
l += (tabWidth - this.$.tabsContainer.offsetWidth);
if (l > 0) {
this.$.tabsContainer.scrollLeft += l;
}
}
},
barTransitionEnd: function(e) {
this._transitionCounter--;
_calcPercent: function(w, w0) {
return 100 * w / w0;
},
_positionBar: function(width, left) {
width = width || 0;
left = left || 0;
this._width = width;
this._left = left;
this.transform(
'translate3d(' + left + '%, 0, 0) scaleX(' + (width / 100) + ')',
this.$.selectionBar);
},
_onBarTransitionEnd: function(e) {
var cl = this.$.selectionBar.classList;
if (cl.contains('expand') && !this._transitionCounter) {
// bar animation: expand -> contract
if (cl.contains('expand')) {
cl.remove('expand');
cl.add('contract');
var s = this.$.selectionBar.style;
var w = 100 / this.items.length;
s.width = w + '%';
s.left = this.selectedIndex * w + '%';
this._positionBar(this._pos.width, this._pos.left);
// bar animation done
} else if (cl.contains('contract')) {
cl.remove('contract');
}
......@@ -128,4 +536,3 @@ To change the sliding bar color:
});
</script>
</polymer-element>
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "polymer",
"private": true,
"version": "1.2.1",
"main": [
"polymer.html"
],
"license": "http://polymer.github.io/LICENSE.txt",
"ignore": [
"/.*",
"/test/",
"gen-changelog.sh"
],
"authors": [
"The Polymer Authors (http://polymer.github.io/AUTHORS.txt)"
],
"repository": {
"type": "git",
"url": "https://github.com/Polymer/polymer.git"
},
"dependencies": {
"platform": "Polymer/platform#^0.4.0",
"core-component-page": "Polymer/core-component-page#^0.4.0"
"webcomponentsjs": "^0.7.2"
},
"devDependencies": {
"web-component-tester": "*"
},
"private": true,
"homepage": "https://github.com/Polymer/polymer",
"version": "0.4.1",
"_release": "0.4.1",
"_release": "1.2.1",
"_resolution": {
"type": "version",
"tag": "0.4.1",
"commit": "c0c8865f5a8f51d48712621f222ac97f00427f66"
"tag": "v1.2.1",
"commit": "be2d57a329244735ca7aac34ac56c96b6270ae79"
},
"_source": "git://github.com/Polymer/polymer.git",
"_target": "^0.4.0",
"_target": "^1.0.0",
"_originalSource": "Polymer/polymer"
}
\ No newline at end of file
# Polymer
[![Analytics](https://ga-beacon.appspot.com/UA-39334307-2/Polymer/polymer/README)](https://github.com/igrigorik/ga-beacon)
Build Status: [http://build.chromium.org/p/client.polymer/waterfall](http://build.chromium.org/p/client.polymer/waterfall)
## Brief Overview
For more detailed info goto [http://polymer-project.org/](http://polymer-project.org/).
Polymer is a new type of library for the web, designed to leverage the existing browser infrastructure to provide the encapsulation and extendability currently only available in JS libraries.
Polymer is based on a set of future technologies, including [Shadow DOM](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html), [Custom Elements](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html) and Model Driven Views. Currently these technologies are implemented as polyfills or shims, but as browsers adopt these features natively, the platform code that drives Polymer evacipates, leaving only the value-adds.
## Tools & Testing
For running tests or building minified files, consult the [tooling information](http://www.polymer-project.org/resources/tooling-strategy.html).
{
"name": "polymer",
"private": true,
"version": "1.2.1",
"main": [
"polymer.html"
],
"license": "http://polymer.github.io/LICENSE.txt",
"ignore": [
"/.*",
"/test/",
"gen-changelog.sh"
],
"authors": [
"The Polymer Authors (http://polymer.github.io/AUTHORS.txt)"
],
"repository": {
"type": "git",
"url": "https://github.com/Polymer/polymer.git"
},
"dependencies": {
"platform": "Polymer/platform#^0.4.0",
"core-component-page": "Polymer/core-component-page#^0.4.0"
}
"webcomponentsjs": "^0.7.2"
},
"devDependencies": {
"web-component-tester": "*"
},
"private": true
}
BUILD LOG
---------
Build Time: 2014-09-18T12:47:15
Build Time: 2015-10-29T15:32:35-0700
NODEJS INFORMATION
==================
nodejs: v0.10.32
chai: 1.9.1
grunt: 0.4.5
grunt-audit: 0.0.3
grunt-concat-sourcemap: 0.4.3
grunt-contrib-concat: 0.4.0
grunt-contrib-uglify: 0.5.1
grunt-karma: 0.8.3
grunt-string-replace: 0.2.7
karma: 0.12.23
karma-crbot-reporter: 0.0.4
karma-ie-launcher: 0.1.5
karma-mocha: 0.1.9
karma-firefox-launcher: 0.1.3
karma-safari-launcher: 0.1.1
karma-script-launcher: 0.1.0
mocha: 1.21.4
nodejs: v4.2.1
gulp: 3.9.0
gulp-audit: 1.0.0
gulp-rename: 1.2.2
gulp-vulcanize: 6.0.1
lazypipe: 0.2.4
polyclean: 1.2.0
web-component-tester: 3.3.29
run-sequence: 1.1.4
del: 1.2.1
gulp-replace: 0.5.4
REPO REVISIONS
==============
polymer-expressions: a1c43d70986be0031206b68f3e17cbf11dbc56e2
polymer-gestures: 1257576a2fe1d7bb507b0c491d30b464eb03311e
polymer-dev: 1d45ec8e7de4495d26610f2dd73b81bfad2a381f
polymer: 5a755342ef6c1bd404d3b4861c3b82d10d57b2ec
BUILD HASHES
============
build/polymer.js: c80909695c132ccf1700bae8e9c51e78ede0cc74
\ No newline at end of file
polymer-mini.html: 88f650dd1b5691577f998049967a6dc9dc456e48
polymer-micro.html: 2261be50c3d6dfe7bd1ae9051a1115f409ef64c3
polymer.html: 0da5e9c32e9ce759647ba6bc64618bb772890acd
\ No newline at end of file
<!--
Copyright (c) 2014 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
-->
<style shim-shadowdom>
/*******************************
Flex Layout
*******************************/
html /deep/ [layout][horizontal], html /deep/ [layout][vertical] {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
html /deep/ [layout][horizontal][inline], html /deep/ [layout][vertical][inline] {
display: -ms-inline-flexbox;
display: -webkit-inline-flex;
display: inline-flex;
}
html /deep/ [layout][horizontal] {
-ms-flex-direction: row;
-webkit-flex-direction: row;
flex-direction: row;
}
html /deep/ [layout][horizontal][reverse] {
-ms-flex-direction: row-reverse;
-webkit-flex-direction: row-reverse;
flex-direction: row-reverse;
}
html /deep/ [layout][vertical] {
-ms-flex-direction: column;
-webkit-flex-direction: column;
flex-direction: column;
}
html /deep/ [layout][vertical][reverse] {
-ms-flex-direction: column-reverse;
-webkit-flex-direction: column-reverse;
flex-direction: column-reverse;
}
html /deep/ [layout][wrap] {
-ms-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
}
html /deep/ [layout][wrap-reverse] {
-ms-flex-wrap: wrap-reverse;
-webkit-flex-wrap: wrap-reverse;
flex-wrap: wrap-reverse;
}
html /deep/ [flex] {
-ms-flex: 1 1 0.000000001px;
-webkit-flex: 1;
flex: 1;
-webkit-flex-basis: 0.000000001px;
flex-basis: 0.000000001px;
}
html /deep/ [vertical][layout] > [flex][auto-vertical], html /deep/ [vertical][layout]::shadow [flex][auto-vertical] {
-ms-flex: 1 1 auto;
-webkit-flex-basis: auto;
flex-basis: auto;
}
html /deep/ [flex][auto] {
-ms-flex: 1 1 auto;
-webkit-flex-basis: auto;
flex-basis: auto;
}
html /deep/ [flex][none] {
-ms-flex: none;
-webkit-flex: none;
flex: none;
}
html /deep/ [flex][one] {
-ms-flex: 1;
-webkit-flex: 1;
flex: 1;
}
html /deep/ [flex][two] {
-ms-flex: 2;
-webkit-flex: 2;
flex: 2;
}
html /deep/ [flex][three] {
-ms-flex: 3;
-webkit-flex: 3;
flex: 3;
}
html /deep/ [flex][four] {
-ms-flex: 4;
-webkit-flex: 4;
flex: 4;
}
html /deep/ [flex][five] {
-ms-flex: 5;
-webkit-flex: 5;
flex: 5;
}
html /deep/ [flex][six] {
-ms-flex: 6;
-webkit-flex: 6;
flex: 6;
}
html /deep/ [flex][seven] {
-ms-flex: 7;
-webkit-flex: 7;
flex: 7;
}
html /deep/ [flex][eight] {
-ms-flex: 8;
-webkit-flex: 8;
flex: 8;
}
html /deep/ [flex][nine] {
-ms-flex: 9;
-webkit-flex: 9;
flex: 9;
}
html /deep/ [flex][ten] {
-ms-flex: 10;
-webkit-flex: 10;
flex: 10;
}
html /deep/ [flex][eleven] {
-ms-flex: 11;
-webkit-flex: 11;
flex: 11;
}
html /deep/ [flex][twelve] {
-ms-flex: 12;
-webkit-flex: 12;
flex: 12;
}
/* alignment in cross axis */
html /deep/ [layout][start] {
-ms-flex-align: start;
-webkit-align-items: flex-start;
align-items: flex-start;
}
html /deep/ [layout][center], html /deep/ [layout][center-center] {
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
html /deep/ [layout][end] {
-ms-flex-align: end;
-webkit-align-items: flex-end;
align-items: flex-end;
}
/* alignment in main axis */
html /deep/ [layout][start-justified] {
-ms-flex-pack: start;
-webkit-justify-content: flex-start;
justify-content: flex-start;
}
html /deep/ [layout][center-justified], html /deep/ [layout][center-center] {
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
html /deep/ [layout][end-justified] {
-ms-flex-pack: end;
-webkit-justify-content: flex-end;
justify-content: flex-end;
}
html /deep/ [layout][around-justified] {
-ms-flex-pack: distribute;
-webkit-justify-content: space-around;
justify-content: space-around;
}
html /deep/ [layout][justified] {
-ms-flex-pack: justify;
-webkit-justify-content: space-between;
justify-content: space-between;
}
/* self alignment */
html /deep/ [self-start] {
-ms-align-self: flex-start;
-webkit-align-self: flex-start;
align-self: flex-start;
}
html /deep/ [self-center] {
-ms-align-self: center;
-webkit-align-self: center;
align-self: center;
}
html /deep/ [self-end] {
-ms-align-self: flex-end;
-webkit-align-self: flex-end;
align-self: flex-end;
}
html /deep/ [self-stretch] {
-ms-align-self: stretch;
-webkit-align-self: stretch;
align-self: stretch;
}
/*******************************
Other Layout
*******************************/
html /deep/ [block] {
display: block;
}
/* ie support for hidden */
html /deep/ [hidden] {
display: none !important;
}
html /deep/ [relative] {
position: relative;
}
html /deep/ [fit] {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
body[fullbleed] {
margin: 0;
height: 100vh;
}
/*******************************
Other
*******************************/
html /deep/ [segment], html /deep/ segment {
display: block;
position: relative;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
margin: 1em 0.5em;
padding: 1em;
background-color: white;
-webkit-box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
border-radius: 5px 5px 5px 5px;
}
</style>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment