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

Unified Diff: chrome/browser/resources/md_history/app.crisper.js

Issue 2270993003: MD History: Add icon in top right of page when showing synced results (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@downloads_wide_toolbar
Patch Set: Move to MD-specific strings Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/resources/md_history/app.js ('k') | chrome/browser/resources/md_history/app.vulcanized.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/resources/md_history/app.crisper.js
diff --git a/chrome/browser/resources/md_history/app.crisper.js b/chrome/browser/resources/md_history/app.crisper.js
index 8b6019c9305ba80c82fc2568195d293badccaf7e..5c59999cf99ed85493d2ec41e31eb44ffd69c83d 100644
--- a/chrome/browser/resources/md_history/app.crisper.js
+++ b/chrome/browser/resources/md_history/app.crisper.js
@@ -2265,733 +2265,930 @@ Polymer.IronControlState = {
}
};
-Polymer.IronButtonStateImpl = {
+Polymer.IronFitBehavior = {
properties: {
- pressed: {
- type: Boolean,
- readOnly: true,
- value: false,
- reflectToAttribute: true,
- observer: '_pressedChanged'
+ sizingTarget: {
+ type: Object,
+ value: function() {
+ return this;
+ }
},
- toggles: {
- type: Boolean,
- value: false,
- reflectToAttribute: true
+ fitInto: {
+ type: Object,
+ value: window
},
- active: {
- type: Boolean,
- value: false,
- notify: true,
- reflectToAttribute: true
+ noOverlap: {
+ type: Boolean
},
- pointerDown: {
- type: Boolean,
- readOnly: true,
- value: false
+ positionTarget: {
+ type: Element
},
- receivedFocusFromKeyboard: {
+ horizontalAlign: {
+ type: String
+ },
+ verticalAlign: {
+ type: String
+ },
+ dynamicAlign: {
+ type: Boolean
+ },
+ horizontalOffset: {
+ type: Number,
+ value: 0,
+ notify: true
+ },
+ verticalOffset: {
+ type: Number,
+ value: 0,
+ notify: true
+ },
+ autoFitOnAttach: {
type: Boolean,
- readOnly: true
+ value: false
},
- ariaActiveAttribute: {
- type: String,
- value: 'aria-pressed',
- observer: '_ariaActiveAttributeChanged'
+ _fitInfo: {
+ type: Object
}
},
- listeners: {
- down: '_downHandler',
- up: '_upHandler',
- tap: '_tapHandler'
- },
- observers: [ '_detectKeyboardFocus(focused)', '_activeChanged(active, ariaActiveAttribute)' ],
- keyBindings: {
- 'enter:keydown': '_asyncClick',
- 'space:keydown': '_spaceKeyDownHandler',
- 'space:keyup': '_spaceKeyUpHandler'
- },
- _mouseEventRe: /^mouse/,
- _tapHandler: function() {
- if (this.toggles) {
- this._userActivate(!this.active);
+ get _fitWidth() {
+ var fitWidth;
+ if (this.fitInto === window) {
+ fitWidth = this.fitInto.innerWidth;
} else {
- this.active = false;
+ fitWidth = this.fitInto.getBoundingClientRect().width;
}
+ return fitWidth;
},
- _detectKeyboardFocus: function(focused) {
- this._setReceivedFocusFromKeyboard(!this.pointerDown && focused);
- },
- _userActivate: function(active) {
- if (this.active !== active) {
- this.active = active;
- this.fire('change');
+ get _fitHeight() {
+ var fitHeight;
+ if (this.fitInto === window) {
+ fitHeight = this.fitInto.innerHeight;
+ } else {
+ fitHeight = this.fitInto.getBoundingClientRect().height;
}
+ return fitHeight;
},
- _downHandler: function(event) {
- this._setPointerDown(true);
- this._setPressed(true);
- this._setReceivedFocusFromKeyboard(false);
+ get _fitLeft() {
+ var fitLeft;
+ if (this.fitInto === window) {
+ fitLeft = 0;
+ } else {
+ fitLeft = this.fitInto.getBoundingClientRect().left;
+ }
+ return fitLeft;
},
- _upHandler: function() {
- this._setPointerDown(false);
- this._setPressed(false);
+ get _fitTop() {
+ var fitTop;
+ if (this.fitInto === window) {
+ fitTop = 0;
+ } else {
+ fitTop = this.fitInto.getBoundingClientRect().top;
+ }
+ return fitTop;
},
- _spaceKeyDownHandler: function(event) {
- var keyboardEvent = event.detail.keyboardEvent;
- var target = Polymer.dom(keyboardEvent).localTarget;
- if (this.isLightDescendant(target)) return;
- keyboardEvent.preventDefault();
- keyboardEvent.stopImmediatePropagation();
- this._setPressed(true);
+ get _defaultPositionTarget() {
+ var parent = Polymer.dom(this).parentNode;
+ if (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
+ parent = parent.host;
+ }
+ return parent;
},
- _spaceKeyUpHandler: function(event) {
- var keyboardEvent = event.detail.keyboardEvent;
- var target = Polymer.dom(keyboardEvent).localTarget;
- if (this.isLightDescendant(target)) return;
- if (this.pressed) {
- this._asyncClick();
+ get _localeHorizontalAlign() {
+ if (this._isRTL) {
+ if (this.horizontalAlign === 'right') {
+ return 'left';
+ }
+ if (this.horizontalAlign === 'left') {
+ return 'right';
+ }
}
- this._setPressed(false);
+ return this.horizontalAlign;
},
- _asyncClick: function() {
- this.async(function() {
- this.click();
- }, 1);
+ attached: function() {
+ this._isRTL = window.getComputedStyle(this).direction == 'rtl';
+ this.positionTarget = this.positionTarget || this._defaultPositionTarget;
+ if (this.autoFitOnAttach) {
+ if (window.getComputedStyle(this).display === 'none') {
+ setTimeout(function() {
+ this.fit();
+ }.bind(this));
+ } else {
+ this.fit();
+ }
+ }
},
- _pressedChanged: function(pressed) {
- this._changedButtonState();
+ fit: function() {
+ this.position();
+ this.constrain();
+ this.center();
},
- _ariaActiveAttributeChanged: function(value, oldValue) {
- if (oldValue && oldValue != value && this.hasAttribute(oldValue)) {
- this.removeAttribute(oldValue);
+ _discoverInfo: function() {
+ if (this._fitInfo) {
+ return;
}
- },
- _activeChanged: function(active, ariaActiveAttribute) {
- if (this.toggles) {
- this.setAttribute(this.ariaActiveAttribute, active ? 'true' : 'false');
- } else {
- this.removeAttribute(this.ariaActiveAttribute);
+ var target = window.getComputedStyle(this);
+ var sizer = window.getComputedStyle(this.sizingTarget);
+ this._fitInfo = {
+ inlineStyle: {
+ top: this.style.top || '',
+ left: this.style.left || '',
+ position: this.style.position || ''
+ },
+ sizerInlineStyle: {
+ maxWidth: this.sizingTarget.style.maxWidth || '',
+ maxHeight: this.sizingTarget.style.maxHeight || '',
+ boxSizing: this.sizingTarget.style.boxSizing || ''
+ },
+ positionedBy: {
+ vertically: target.top !== 'auto' ? 'top' : target.bottom !== 'auto' ? 'bottom' : null,
+ horizontally: target.left !== 'auto' ? 'left' : target.right !== 'auto' ? 'right' : null
+ },
+ sizedBy: {
+ height: sizer.maxHeight !== 'none',
+ width: sizer.maxWidth !== 'none',
+ minWidth: parseInt(sizer.minWidth, 10) || 0,
+ minHeight: parseInt(sizer.minHeight, 10) || 0
+ },
+ margin: {
+ top: parseInt(target.marginTop, 10) || 0,
+ right: parseInt(target.marginRight, 10) || 0,
+ bottom: parseInt(target.marginBottom, 10) || 0,
+ left: parseInt(target.marginLeft, 10) || 0
+ }
+ };
+ if (this.verticalOffset) {
+ this._fitInfo.margin.top = this._fitInfo.margin.bottom = this.verticalOffset;
+ this._fitInfo.inlineStyle.marginTop = this.style.marginTop || '';
+ this._fitInfo.inlineStyle.marginBottom = this.style.marginBottom || '';
+ this.style.marginTop = this.style.marginBottom = this.verticalOffset + 'px';
+ }
+ if (this.horizontalOffset) {
+ this._fitInfo.margin.left = this._fitInfo.margin.right = this.horizontalOffset;
+ this._fitInfo.inlineStyle.marginLeft = this.style.marginLeft || '';
+ this._fitInfo.inlineStyle.marginRight = this.style.marginRight || '';
+ this.style.marginLeft = this.style.marginRight = this.horizontalOffset + 'px';
}
- this._changedButtonState();
},
- _controlStateChanged: function() {
- if (this.disabled) {
- this._setPressed(false);
- } else {
- this._changedButtonState();
+ resetFit: function() {
+ var info = this._fitInfo || {};
+ for (var property in info.sizerInlineStyle) {
+ this.sizingTarget.style[property] = info.sizerInlineStyle[property];
+ }
+ for (var property in info.inlineStyle) {
+ this.style[property] = info.inlineStyle[property];
}
+ this._fitInfo = null;
},
- _changedButtonState: function() {
- if (this._buttonStateChanged) {
- this._buttonStateChanged();
+ refit: function() {
+ var scrollLeft = this.sizingTarget.scrollLeft;
+ var scrollTop = this.sizingTarget.scrollTop;
+ this.resetFit();
+ this.fit();
+ this.sizingTarget.scrollLeft = scrollLeft;
+ this.sizingTarget.scrollTop = scrollTop;
+ },
+ position: function() {
+ if (!this.horizontalAlign && !this.verticalAlign) {
+ return;
}
- }
-};
-
-Polymer.IronButtonState = [ Polymer.IronA11yKeysBehavior, Polymer.IronButtonStateImpl ];
+ this._discoverInfo();
+ this.style.position = 'fixed';
+ this.sizingTarget.style.boxSizing = 'border-box';
+ this.style.left = '0px';
+ this.style.top = '0px';
+ var rect = this.getBoundingClientRect();
+ var positionRect = this.__getNormalizedRect(this.positionTarget);
+ var fitRect = this.__getNormalizedRect(this.fitInto);
+ var margin = this._fitInfo.margin;
+ var size = {
+ width: rect.width + margin.left + margin.right,
+ height: rect.height + margin.top + margin.bottom
+ };
+ var position = this.__getPosition(this._localeHorizontalAlign, this.verticalAlign, size, positionRect, fitRect);
+ var left = position.left + margin.left;
+ var top = position.top + margin.top;
+ var right = Math.min(fitRect.right - margin.right, left + rect.width);
+ var bottom = Math.min(fitRect.bottom - margin.bottom, top + rect.height);
+ var minWidth = this._fitInfo.sizedBy.minWidth;
+ var minHeight = this._fitInfo.sizedBy.minHeight;
+ if (left < margin.left) {
+ left = margin.left;
+ if (right - left < minWidth) {
+ left = right - minWidth;
+ }
+ }
+ if (top < margin.top) {
+ top = margin.top;
+ if (bottom - top < minHeight) {
+ top = bottom - minHeight;
+ }
+ }
+ this.sizingTarget.style.maxWidth = right - left + 'px';
+ this.sizingTarget.style.maxHeight = bottom - top + 'px';
+ this.style.left = left - rect.left + 'px';
+ this.style.top = top - rect.top + 'px';
+ },
+ constrain: function() {
+ if (this.horizontalAlign || this.verticalAlign) {
+ return;
+ }
+ this._discoverInfo();
+ var info = this._fitInfo;
+ if (!info.positionedBy.vertically) {
+ this.style.position = 'fixed';
+ this.style.top = '0px';
+ }
+ if (!info.positionedBy.horizontally) {
+ this.style.position = 'fixed';
+ this.style.left = '0px';
+ }
+ this.sizingTarget.style.boxSizing = 'border-box';
+ var rect = this.getBoundingClientRect();
+ if (!info.sizedBy.height) {
+ this.__sizeDimension(rect, info.positionedBy.vertically, 'top', 'bottom', 'Height');
+ }
+ if (!info.sizedBy.width) {
+ this.__sizeDimension(rect, info.positionedBy.horizontally, 'left', 'right', 'Width');
+ }
+ },
+ _sizeDimension: function(rect, positionedBy, start, end, extent) {
+ this.__sizeDimension(rect, positionedBy, start, end, extent);
+ },
+ __sizeDimension: function(rect, positionedBy, start, end, extent) {
+ var info = this._fitInfo;
+ var fitRect = this.__getNormalizedRect(this.fitInto);
+ var max = extent === 'Width' ? fitRect.width : fitRect.height;
+ var flip = positionedBy === end;
+ var offset = flip ? max - rect[end] : rect[start];
+ var margin = info.margin[flip ? start : end];
+ var offsetExtent = 'offset' + extent;
+ var sizingOffset = this[offsetExtent] - this.sizingTarget[offsetExtent];
+ this.sizingTarget.style['max' + extent] = max - margin - offset - sizingOffset + 'px';
+ },
+ center: function() {
+ if (this.horizontalAlign || this.verticalAlign) {
+ return;
+ }
+ this._discoverInfo();
+ var positionedBy = this._fitInfo.positionedBy;
+ if (positionedBy.vertically && positionedBy.horizontally) {
+ return;
+ }
+ this.style.position = 'fixed';
+ if (!positionedBy.vertically) {
+ this.style.top = '0px';
+ }
+ if (!positionedBy.horizontally) {
+ this.style.left = '0px';
+ }
+ var rect = this.getBoundingClientRect();
+ var fitRect = this.__getNormalizedRect(this.fitInto);
+ if (!positionedBy.vertically) {
+ var top = fitRect.top - rect.top + (fitRect.height - rect.height) / 2;
+ this.style.top = top + 'px';
+ }
+ if (!positionedBy.horizontally) {
+ var left = fitRect.left - rect.left + (fitRect.width - rect.width) / 2;
+ this.style.left = left + 'px';
+ }
+ },
+ __getNormalizedRect: function(target) {
+ if (target === document.documentElement || target === window) {
+ return {
+ top: 0,
+ left: 0,
+ width: window.innerWidth,
+ height: window.innerHeight,
+ right: window.innerWidth,
+ bottom: window.innerHeight
+ };
+ }
+ return target.getBoundingClientRect();
+ },
+ __getCroppedArea: function(position, size, fitRect) {
+ var verticalCrop = Math.min(0, position.top) + Math.min(0, fitRect.bottom - (position.top + size.height));
+ var horizontalCrop = Math.min(0, position.left) + Math.min(0, fitRect.right - (position.left + size.width));
+ return Math.abs(verticalCrop) * size.width + Math.abs(horizontalCrop) * size.height;
+ },
+ __getPosition: function(hAlign, vAlign, size, positionRect, fitRect) {
+ var positions = [ {
+ verticalAlign: 'top',
+ horizontalAlign: 'left',
+ top: positionRect.top,
+ left: positionRect.left
+ }, {
+ verticalAlign: 'top',
+ horizontalAlign: 'right',
+ top: positionRect.top,
+ left: positionRect.right - size.width
+ }, {
+ verticalAlign: 'bottom',
+ horizontalAlign: 'left',
+ top: positionRect.bottom - size.height,
+ left: positionRect.left
+ }, {
+ verticalAlign: 'bottom',
+ horizontalAlign: 'right',
+ top: positionRect.bottom - size.height,
+ left: positionRect.right - size.width
+ } ];
+ if (this.noOverlap) {
+ for (var i = 0, l = positions.length; i < l; i++) {
+ var copy = {};
+ for (var key in positions[i]) {
+ copy[key] = positions[i][key];
+ }
+ positions.push(copy);
+ }
+ positions[0].top = positions[1].top += positionRect.height;
+ positions[2].top = positions[3].top -= positionRect.height;
+ positions[4].left = positions[6].left += positionRect.width;
+ positions[5].left = positions[7].left -= positionRect.width;
+ }
+ vAlign = vAlign === 'auto' ? null : vAlign;
+ hAlign = hAlign === 'auto' ? null : hAlign;
+ var position;
+ for (var i = 0; i < positions.length; i++) {
+ var pos = positions[i];
+ if (!this.dynamicAlign && !this.noOverlap && pos.verticalAlign === vAlign && pos.horizontalAlign === hAlign) {
+ position = pos;
+ break;
+ }
+ var alignOk = (!vAlign || pos.verticalAlign === vAlign) && (!hAlign || pos.horizontalAlign === hAlign);
+ if (!this.dynamicAlign && !alignOk) {
+ continue;
+ }
+ position = position || pos;
+ pos.croppedArea = this.__getCroppedArea(pos, size, fitRect);
+ var diff = pos.croppedArea - position.croppedArea;
+ if (diff < 0 || diff === 0 && alignOk) {
+ position = pos;
+ }
+ if (position.croppedArea === 0 && alignOk) {
+ break;
+ }
+ }
+ return position;
+ }
+};
(function() {
- var Utility = {
- distance: function(x1, y1, x2, y2) {
- var xDelta = x1 - x2;
- var yDelta = y1 - y2;
- return Math.sqrt(xDelta * xDelta + yDelta * yDelta);
+ 'use strict';
+ Polymer({
+ is: 'iron-overlay-backdrop',
+ properties: {
+ opened: {
+ reflectToAttribute: true,
+ type: Boolean,
+ value: false,
+ observer: '_openedChanged'
+ }
},
- now: window.performance && window.performance.now ? window.performance.now.bind(window.performance) : Date.now
- };
- 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();
+ listeners: {
+ transitionend: '_onTransitionend'
},
- 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);
- }
- };
- function Ripple(element) {
- this.element = element;
- this.color = window.getComputedStyle(element).color;
- 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);
- this.resetInteractionState();
- }
- Ripple.MAX_RADIUS = 300;
- Ripple.prototype = {
- get recenters() {
- return this.element.recenters;
+ created: function() {
+ this.__openedRaf = null;
},
- get center() {
- return this.element.center;
+ attached: function() {
+ this.opened && this._openedChanged(this.opened);
},
- get mouseDownElapsed() {
- var elapsed;
- if (!this.mouseDownStart) {
- return 0;
- }
- elapsed = Utility.now() - this.mouseDownStart;
- if (this.mouseUpStart) {
- elapsed -= this.mouseUpElapsed;
+ prepare: function() {
+ if (this.opened && !this.parentNode) {
+ Polymer.dom(document.body).appendChild(this);
}
- return elapsed;
},
- get mouseUpElapsed() {
- return this.mouseUpStart ? Utility.now() - this.mouseUpStart : 0;
+ open: function() {
+ this.opened = true;
},
- get mouseDownElapsedSeconds() {
- return this.mouseDownElapsed / 1e3;
- },
- get mouseUpElapsedSeconds() {
- return this.mouseUpElapsed / 1e3;
- },
- 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 - .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() {
- var outerOpacity = this.mouseUpElapsedSeconds * .3;
- var waveOpacity = this.opacity;
- return Math.max(0, Math.min(outerOpacity, waveOpacity));
- },
- get isOpacityFullyDecayed() {
- return this.opacity < .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;
- },
- get translationFraction() {
- return Math.min(1, this.radius / this.containerMetrics.size * 2 / Math.sqrt(2));
- },
- get xNow() {
- if (this.xEnd) {
- return this.xStart + this.translationFraction * (this.xEnd - this.xStart);
- }
- return this.xStart;
- },
- get yNow() {
- if (this.yEnd) {
- return this.yStart + this.translationFraction * (this.yEnd - this.yStart);
- }
- 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;
- 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)';
- },
- 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';
+ close: function() {
+ this.opened = false;
},
- upAction: function(event) {
- if (!this.isMouseDown) {
- return;
+ complete: function() {
+ if (!this.opened && this.parentNode === document.body) {
+ Polymer.dom(this.parentNode).removeChild(this);
}
- this.mouseUpStart = Utility.now();
},
- remove: function() {
- Polymer.dom(this.waveContainer.parentNode).removeChild(this.waveContainer);
- }
- };
- Polymer({
- is: 'paper-ripple',
- behaviors: [ Polymer.IronA11yKeysBehavior ],
- properties: {
- initialOpacity: {
- type: Number,
- value: .25
- },
- opacityDecayVelocity: {
- type: Number,
- value: .8
- },
- recenters: {
- type: Boolean,
- value: false
- },
- center: {
- type: Boolean,
- value: false
- },
- ripples: {
- type: Array,
- value: function() {
- return [];
- }
- },
- animating: {
- type: Boolean,
- readOnly: true,
- reflectToAttribute: true,
- value: false
- },
- holdDown: {
- type: Boolean,
- value: false,
- observer: '_holdDownChanged'
- },
- noink: {
- type: Boolean,
- value: false
- },
- _animating: {
- type: Boolean
- },
- _boundAnimate: {
- type: Function,
- value: function() {
- return this.animate.bind(this);
- }
+ _onTransitionend: function(event) {
+ if (event && event.target === this) {
+ this.complete();
}
},
- get target() {
- return this.keyEventTarget;
- },
- keyBindings: {
- 'enter:keydown': '_onEnterKeydown',
- 'space:keydown': '_onSpaceKeydown',
- 'space:keyup': '_onSpaceKeyup'
- },
- attached: function() {
- if (this.parentNode.nodeType == 11) {
- this.keyEventTarget = Polymer.dom(this).getOwnerRoot().host;
+ _openedChanged: function(opened) {
+ if (opened) {
+ this.prepare();
} else {
- this.keyEventTarget = this.parentNode;
- }
- var keyEventTarget = this.keyEventTarget;
- this.listen(keyEventTarget, 'up', 'uiUpAction');
- this.listen(keyEventTarget, 'down', 'uiDownAction');
- },
- detached: function() {
- this.unlisten(this.keyEventTarget, 'up', 'uiUpAction');
- this.unlisten(this.keyEventTarget, 'down', 'uiDownAction');
- this.keyEventTarget = null;
- },
- get shouldKeepAnimating() {
- for (var index = 0; index < this.ripples.length; ++index) {
- if (!this.ripples[index].isAnimationComplete) {
- return true;
+ var cs = window.getComputedStyle(this);
+ if (cs.transitionDuration === '0s' || cs.opacity == 0) {
+ this.complete();
}
}
- return false;
- },
- simulatedRipple: function() {
- this.downAction(null);
- this.async(function() {
- this.upAction();
- }, 1);
- },
- uiDownAction: function(event) {
- if (!this.noink) {
- this.downAction(event);
- }
- },
- downAction: function(event) {
- if (this.holdDown && this.ripples.length > 0) {
+ if (!this.isAttached) {
return;
}
- var ripple = this.addRipple();
- ripple.downAction(event);
- if (!this._animating) {
- this._animating = true;
- this.animate();
- }
- },
- uiUpAction: function(event) {
- if (!this.noink) {
- this.upAction(event);
- }
- },
- upAction: function(event) {
- if (this.holdDown) {
- return;
- }
- this.ripples.forEach(function(ripple) {
- ripple.upAction(event);
- });
- this._animating = true;
- this.animate();
- },
- onAnimationComplete: function() {
- this._animating = false;
- this.$.background.style.backgroundColor = null;
- this.fire('transitionend');
- },
- addRipple: function() {
- var ripple = new Ripple(this);
- Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);
- this.$.background.style.backgroundColor = ripple.color;
- this.ripples.push(ripple);
- this._setAnimating(true);
- return ripple;
- },
- removeRipple: function(ripple) {
- var rippleIndex = this.ripples.indexOf(ripple);
- if (rippleIndex < 0) {
- return;
- }
- this.ripples.splice(rippleIndex, 1);
- ripple.remove();
- if (!this.ripples.length) {
- this._setAnimating(false);
- }
- },
- animate: function() {
- if (!this._animating) {
- return;
- }
- var index;
- var ripple;
- for (index = 0; index < this.ripples.length; ++index) {
- ripple = this.ripples[index];
- ripple.draw();
- this.$.background.style.opacity = ripple.outerOpacity;
- if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) {
- this.removeRipple(ripple);
- }
- }
- if (!this.shouldKeepAnimating && this.ripples.length === 0) {
- this.onAnimationComplete();
- } else {
- window.requestAnimationFrame(this._boundAnimate);
- }
- },
- _onEnterKeydown: function() {
- this.uiDownAction();
- this.async(this.uiUpAction, 1);
- },
- _onSpaceKeydown: function() {
- this.uiDownAction();
- },
- _onSpaceKeyup: function() {
- this.uiUpAction();
- },
- _holdDownChanged: function(newVal, oldVal) {
- if (oldVal === undefined) {
- return;
- }
- if (newVal) {
- this.downAction();
- } else {
- this.upAction();
+ if (this.__openedRaf) {
+ window.cancelAnimationFrame(this.__openedRaf);
+ this.__openedRaf = null;
}
+ this.scrollTop = this.scrollTop;
+ this.__openedRaf = window.requestAnimationFrame(function() {
+ this.__openedRaf = null;
+ this.toggleClass('opened', this.opened);
+ }.bind(this));
}
});
})();
-Polymer.PaperRippleBehavior = {
- properties: {
- noink: {
- type: Boolean,
- observer: '_noinkChanged'
- },
- _rippleContainer: {
- type: Object
+Polymer.IronOverlayManagerClass = function() {
+ this._overlays = [];
+ this._minimumZ = 101;
+ this._backdropElement = null;
+ Polymer.Gestures.add(document, 'tap', this._onCaptureClick.bind(this));
+ document.addEventListener('focus', this._onCaptureFocus.bind(this), true);
+ document.addEventListener('keydown', this._onCaptureKeyDown.bind(this), true);
+};
+
+Polymer.IronOverlayManagerClass.prototype = {
+ constructor: Polymer.IronOverlayManagerClass,
+ get backdropElement() {
+ if (!this._backdropElement) {
+ this._backdropElement = document.createElement('iron-overlay-backdrop');
}
+ return this._backdropElement;
},
- _buttonStateChanged: function() {
- if (this.focused) {
- this.ensureRipple();
+ get deepActiveElement() {
+ var active = document.activeElement || document.body;
+ while (active.root && Polymer.dom(active.root).activeElement) {
+ active = Polymer.dom(active.root).activeElement;
}
+ return active;
},
- _downHandler: function(event) {
- Polymer.IronButtonStateImpl._downHandler.call(this, event);
- if (this.pressed) {
- this.ensureRipple(event);
+ _bringOverlayAtIndexToFront: function(i) {
+ var overlay = this._overlays[i];
+ if (!overlay) {
+ return;
}
+ var lastI = this._overlays.length - 1;
+ var currentOverlay = this._overlays[lastI];
+ if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay)) {
+ lastI--;
+ }
+ if (i >= lastI) {
+ return;
+ }
+ var minimumZ = Math.max(this.currentOverlayZ(), this._minimumZ);
+ if (this._getZ(overlay) <= minimumZ) {
+ this._applyOverlayZ(overlay, minimumZ);
+ }
+ while (i < lastI) {
+ this._overlays[i] = this._overlays[i + 1];
+ i++;
+ }
+ this._overlays[lastI] = overlay;
},
- ensureRipple: function(optTriggeringEvent) {
- if (!this.hasRipple()) {
- this._ripple = this._createRipple();
- this._ripple.noink = this.noink;
- var rippleContainer = this._rippleContainer || this.root;
- if (rippleContainer) {
- Polymer.dom(rippleContainer).appendChild(this._ripple);
- }
- if (optTriggeringEvent) {
- var domContainer = Polymer.dom(this._rippleContainer || this);
- var target = Polymer.dom(optTriggeringEvent).rootTarget;
- if (domContainer.deepContains(target)) {
- this._ripple.uiDownAction(optTriggeringEvent);
- }
- }
+ addOrRemoveOverlay: function(overlay) {
+ if (overlay.opened) {
+ this.addOverlay(overlay);
+ } else {
+ this.removeOverlay(overlay);
}
},
- getRipple: function() {
- this.ensureRipple();
- return this._ripple;
+ addOverlay: function(overlay) {
+ var i = this._overlays.indexOf(overlay);
+ if (i >= 0) {
+ this._bringOverlayAtIndexToFront(i);
+ this.trackBackdrop();
+ return;
+ }
+ var insertionIndex = this._overlays.length;
+ var currentOverlay = this._overlays[insertionIndex - 1];
+ var minimumZ = Math.max(this._getZ(currentOverlay), this._minimumZ);
+ var newZ = this._getZ(overlay);
+ if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay)) {
+ this._applyOverlayZ(currentOverlay, minimumZ);
+ insertionIndex--;
+ var previousOverlay = this._overlays[insertionIndex - 1];
+ minimumZ = Math.max(this._getZ(previousOverlay), this._minimumZ);
+ }
+ if (newZ <= minimumZ) {
+ this._applyOverlayZ(overlay, minimumZ);
+ }
+ this._overlays.splice(insertionIndex, 0, overlay);
+ this.trackBackdrop();
},
- hasRipple: function() {
- return Boolean(this._ripple);
+ removeOverlay: function(overlay) {
+ var i = this._overlays.indexOf(overlay);
+ if (i === -1) {
+ return;
+ }
+ this._overlays.splice(i, 1);
+ this.trackBackdrop();
},
- _createRipple: function() {
- return document.createElement('paper-ripple');
+ currentOverlay: function() {
+ var i = this._overlays.length - 1;
+ return this._overlays[i];
},
- _noinkChanged: function(noink) {
- if (this.hasRipple()) {
- this._ripple.noink = noink;
- }
- }
-};
-
-Polymer.PaperButtonBehaviorImpl = {
- properties: {
- elevation: {
- type: Number,
- reflectToAttribute: true,
- readOnly: true
- }
+ currentOverlayZ: function() {
+ return this._getZ(this.currentOverlay());
},
- observers: [ '_calculateElevation(focused, disabled, active, pressed, receivedFocusFromKeyboard)', '_computeKeyboardClass(receivedFocusFromKeyboard)' ],
- hostAttributes: {
- role: 'button',
- tabindex: '0',
- animated: true
+ ensureMinimumZ: function(minimumZ) {
+ this._minimumZ = Math.max(this._minimumZ, minimumZ);
},
- _calculateElevation: function() {
- var e = 1;
- if (this.disabled) {
- e = 0;
- } else if (this.active || this.pressed) {
- e = 4;
- } else if (this.receivedFocusFromKeyboard) {
- e = 3;
+ focusOverlay: function() {
+ var current = this.currentOverlay();
+ if (current) {
+ current._applyFocus();
}
- this._setElevation(e);
},
- _computeKeyboardClass: function(receivedFocusFromKeyboard) {
- this.toggleClass('keyboard-focus', receivedFocusFromKeyboard);
- },
- _spaceKeyDownHandler: function(event) {
- Polymer.IronButtonStateImpl._spaceKeyDownHandler.call(this, event);
- if (this.hasRipple() && this.getRipple().ripples.length < 1) {
- this._ripple.uiDownAction();
+ trackBackdrop: function() {
+ var overlay = this._overlayWithBackdrop();
+ if (!overlay && !this._backdropElement) {
+ return;
}
+ this.backdropElement.style.zIndex = this._getZ(overlay) - 1;
+ this.backdropElement.opened = !!overlay;
},
- _spaceKeyUpHandler: function(event) {
- Polymer.IronButtonStateImpl._spaceKeyUpHandler.call(this, event);
- if (this.hasRipple()) {
- this._ripple.uiUpAction();
+ getBackdrops: function() {
+ var backdrops = [];
+ for (var i = 0; i < this._overlays.length; i++) {
+ if (this._overlays[i].withBackdrop) {
+ backdrops.push(this._overlays[i]);
+ }
}
- }
-};
-
-Polymer.PaperButtonBehavior = [ Polymer.IronButtonState, Polymer.IronControlState, Polymer.PaperRippleBehavior, Polymer.PaperButtonBehaviorImpl ];
-
-Polymer({
- is: 'paper-button',
- behaviors: [ Polymer.PaperButtonBehavior ],
- properties: {
- raised: {
- type: Boolean,
- reflectToAttribute: true,
- value: false,
- observer: '_calculateElevation'
+ return backdrops;
+ },
+ backdropZ: function() {
+ return this._getZ(this._overlayWithBackdrop()) - 1;
+ },
+ _overlayWithBackdrop: function() {
+ for (var i = 0; i < this._overlays.length; i++) {
+ if (this._overlays[i].withBackdrop) {
+ return this._overlays[i];
+ }
}
},
- _calculateElevation: function() {
- if (!this.raised) {
- this._setElevation(0);
- } else {
- Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this);
+ _getZ: function(overlay) {
+ var z = this._minimumZ;
+ if (overlay) {
+ var z1 = Number(overlay.style.zIndex || window.getComputedStyle(overlay).zIndex);
+ if (z1 === z1) {
+ z = z1;
+ }
+ }
+ return z;
+ },
+ _setZ: function(element, z) {
+ element.style.zIndex = z;
+ },
+ _applyOverlayZ: function(overlay, aboveZ) {
+ this._setZ(overlay, aboveZ + 2);
+ },
+ _overlayInPath: function(path) {
+ path = path || [];
+ for (var i = 0; i < path.length; i++) {
+ if (path[i]._manager === this) {
+ return path[i];
+ }
+ }
+ },
+ _onCaptureClick: function(event) {
+ var overlay = this.currentOverlay();
+ if (overlay && this._overlayInPath(Polymer.dom(event).path) !== overlay) {
+ overlay._onCaptureClick(event);
}
+ },
+ _onCaptureFocus: function(event) {
+ var overlay = this.currentOverlay();
+ if (overlay) {
+ overlay._onCaptureFocus(event);
+ }
+ },
+ _onCaptureKeyDown: function(event) {
+ var overlay = this.currentOverlay();
+ if (overlay) {
+ if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(event, 'esc')) {
+ overlay._onCaptureEsc(event);
+ } else if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(event, 'tab')) {
+ overlay._onCaptureTab(event);
+ }
+ }
+ },
+ _shouldBeBehindOverlay: function(overlay1, overlay2) {
+ return !overlay1.alwaysOnTop && overlay2.alwaysOnTop;
}
-});
+};
+
+Polymer.IronOverlayManager = new Polymer.IronOverlayManagerClass();
(function() {
- var metaDatas = {};
- var metaArrays = {};
- var singleton = null;
- Polymer.IronMeta = Polymer({
- is: 'iron-meta',
+ 'use strict';
+ Polymer.IronOverlayBehaviorImpl = {
properties: {
- type: {
- type: String,
- value: 'default',
- observer: '_typeChanged'
+ opened: {
+ observer: '_openedChanged',
+ type: Boolean,
+ value: false,
+ notify: true
},
- key: {
- type: String,
- observer: '_keyChanged'
+ canceled: {
+ observer: '_canceledChanged',
+ readOnly: true,
+ type: Boolean,
+ value: false
},
- value: {
- type: Object,
- notify: true,
- observer: '_valueChanged'
+ withBackdrop: {
+ observer: '_withBackdropChanged',
+ type: Boolean
},
- self: {
+ noAutoFocus: {
type: Boolean,
- observer: '_selfChanged'
+ value: false
},
- list: {
- type: Array,
- notify: true
+ noCancelOnEscKey: {
+ type: Boolean,
+ value: false
+ },
+ noCancelOnOutsideClick: {
+ type: Boolean,
+ value: false
+ },
+ closingReason: {
+ type: Object
+ },
+ restoreFocusOnClose: {
+ type: Boolean,
+ value: false
+ },
+ alwaysOnTop: {
+ type: Boolean
+ },
+ _manager: {
+ type: Object,
+ value: Polymer.IronOverlayManager
+ },
+ _focusedChild: {
+ type: Object
}
},
- hostAttributes: {
- hidden: true
+ listeners: {
+ 'iron-resize': '_onIronResize'
},
- factoryImpl: function(config) {
- if (config) {
- for (var n in config) {
- switch (n) {
- case 'type':
- case 'key':
- case 'value':
- this[n] = config[n];
- break;
- }
- }
- }
+ get backdropElement() {
+ return this._manager.backdropElement;
},
- created: function() {
- this._metaDatas = metaDatas;
- this._metaArrays = metaArrays;
+ get _focusNode() {
+ return this._focusedChild || Polymer.dom(this).querySelector('[autofocus]') || this;
},
- _keyChanged: function(key, old) {
- this._resetRegistration(old);
+ get _focusableNodes() {
+ var FOCUSABLE_WITH_DISABLED = [ 'a[href]', 'area[href]', 'iframe', '[tabindex]', '[contentEditable=true]' ];
+ var FOCUSABLE_WITHOUT_DISABLED = [ 'input', 'select', 'textarea', 'button' ];
+ var selector = FOCUSABLE_WITH_DISABLED.join(':not([tabindex="-1"]),') + ':not([tabindex="-1"]),' + FOCUSABLE_WITHOUT_DISABLED.join(':not([disabled]):not([tabindex="-1"]),') + ':not([disabled]):not([tabindex="-1"])';
+ var focusables = Polymer.dom(this).querySelectorAll(selector);
+ if (this.tabIndex >= 0) {
+ focusables.splice(0, 0, this);
+ }
+ return focusables.sort(function(a, b) {
+ if (a.tabIndex === b.tabIndex) {
+ return 0;
+ }
+ if (a.tabIndex === 0 || a.tabIndex > b.tabIndex) {
+ return 1;
+ }
+ return -1;
+ });
},
- _valueChanged: function(value) {
- this._resetRegistration(this.key);
+ ready: function() {
+ this.__isAnimating = false;
+ this.__shouldRemoveTabIndex = false;
+ this.__firstFocusableNode = this.__lastFocusableNode = null;
+ this.__raf = null;
+ this.__restoreFocusNode = null;
+ this._ensureSetup();
},
- _selfChanged: function(self) {
- if (self) {
- this.value = this;
+ attached: function() {
+ if (this.opened) {
+ this._openedChanged(this.opened);
}
+ this._observer = Polymer.dom(this).observeNodes(this._onNodesChange);
},
- _typeChanged: function(type) {
- this._unregisterKey(this.key);
- if (!metaDatas[type]) {
- metaDatas[type] = {};
- }
- this._metaData = metaDatas[type];
- if (!metaArrays[type]) {
- metaArrays[type] = [];
+ detached: function() {
+ Polymer.dom(this).unobserveNodes(this._observer);
+ this._observer = null;
+ if (this.__raf) {
+ window.cancelAnimationFrame(this.__raf);
+ this.__raf = null;
}
- this.list = metaArrays[type];
- this._registerKeyValue(this.key, this.value);
+ this._manager.removeOverlay(this);
},
- byKey: function(key) {
- return this._metaData && this._metaData[key];
+ toggle: function() {
+ this._setCanceled(false);
+ this.opened = !this.opened;
},
- _resetRegistration: function(oldKey) {
- this._unregisterKey(oldKey);
- this._registerKeyValue(this.key, this.value);
+ open: function() {
+ this._setCanceled(false);
+ this.opened = true;
},
- _unregisterKey: function(key) {
- this._unregister(key, this._metaData, this.list);
+ close: function() {
+ this._setCanceled(false);
+ this.opened = false;
},
- _registerKeyValue: function(key, value) {
- this._register(key, value, this._metaData, this.list);
+ cancel: function(event) {
+ var cancelEvent = this.fire('iron-overlay-canceled', event, {
+ cancelable: true
+ });
+ if (cancelEvent.defaultPrevented) {
+ return;
+ }
+ this._setCanceled(true);
+ this.opened = false;
},
- _register: function(key, value, data, list) {
- if (key && data && value !== undefined) {
- data[key] = value;
- list.push(value);
+ _ensureSetup: function() {
+ if (this._overlaySetup) {
+ return;
}
+ this._overlaySetup = true;
+ this.style.outline = 'none';
+ this.style.display = 'none';
},
- _unregister: function(key, data, list) {
- if (key && data) {
- if (key in data) {
- var value = data[key];
- delete data[key];
- this.arrayDelete(list, value);
- }
+ _openedChanged: function(opened) {
+ if (opened) {
+ this.removeAttribute('aria-hidden');
+ } else {
+ this.setAttribute('aria-hidden', 'true');
}
- }
- });
- Polymer.IronMeta.getIronMeta = function getIronMeta() {
- if (singleton === null) {
- singleton = new Polymer.IronMeta();
- }
- return singleton;
- };
- Polymer.IronMetaQuery = Polymer({
- is: 'iron-meta-query',
- properties: {
- type: {
- type: String,
- value: 'default',
- observer: '_typeChanged'
+ if (!this.isAttached) {
+ return;
+ }
+ this.__isAnimating = true;
+ this.__onNextAnimationFrame(this.__openedChanged);
+ },
+ _canceledChanged: function() {
+ this.closingReason = this.closingReason || {};
+ this.closingReason.canceled = this.canceled;
+ },
+ _withBackdropChanged: function() {
+ if (this.withBackdrop && !this.hasAttribute('tabindex')) {
+ this.setAttribute('tabindex', '-1');
+ this.__shouldRemoveTabIndex = true;
+ } else if (this.__shouldRemoveTabIndex) {
+ this.removeAttribute('tabindex');
+ this.__shouldRemoveTabIndex = false;
+ }
+ if (this.opened && this.isAttached) {
+ this._manager.trackBackdrop();
+ }
+ },
+ _prepareRenderOpened: function() {
+ this.__restoreFocusNode = this._manager.deepActiveElement;
+ this._preparePositioning();
+ this.refit();
+ this._finishPositioning();
+ if (this.noAutoFocus && document.activeElement === this._focusNode) {
+ this._focusNode.blur();
+ this.__restoreFocusNode.focus();
+ }
+ },
+ _renderOpened: function() {
+ this._finishRenderOpened();
+ },
+ _renderClosed: function() {
+ this._finishRenderClosed();
+ },
+ _finishRenderOpened: function() {
+ this.notifyResize();
+ this.__isAnimating = false;
+ var focusableNodes = this._focusableNodes;
+ this.__firstFocusableNode = focusableNodes[0];
+ this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1];
+ this.fire('iron-overlay-opened');
+ },
+ _finishRenderClosed: function() {
+ this.style.display = 'none';
+ this.style.zIndex = '';
+ this.notifyResize();
+ this.__isAnimating = false;
+ this.fire('iron-overlay-closed', this.closingReason);
+ },
+ _preparePositioning: function() {
+ this.style.transition = this.style.webkitTransition = 'none';
+ this.style.transform = this.style.webkitTransform = 'none';
+ this.style.display = '';
+ },
+ _finishPositioning: function() {
+ this.style.display = 'none';
+ this.scrollTop = this.scrollTop;
+ this.style.transition = this.style.webkitTransition = '';
+ this.style.transform = this.style.webkitTransform = '';
+ this.style.display = '';
+ this.scrollTop = this.scrollTop;
+ },
+ _applyFocus: function() {
+ if (this.opened) {
+ if (!this.noAutoFocus) {
+ this._focusNode.focus();
+ }
+ } else {
+ this._focusNode.blur();
+ this._focusedChild = null;
+ if (this.restoreFocusOnClose && this.__restoreFocusNode) {
+ this.__restoreFocusNode.focus();
+ }
+ this.__restoreFocusNode = null;
+ var currentOverlay = this._manager.currentOverlay();
+ if (currentOverlay && this !== currentOverlay) {
+ currentOverlay._applyFocus();
+ }
+ }
+ },
+ _onCaptureClick: function(event) {
+ if (!this.noCancelOnOutsideClick) {
+ this.cancel(event);
+ }
+ },
+ _onCaptureFocus: function(event) {
+ if (!this.withBackdrop) {
+ return;
+ }
+ var path = Polymer.dom(event).path;
+ if (path.indexOf(this) === -1) {
+ event.stopPropagation();
+ this._applyFocus();
+ } else {
+ this._focusedChild = path[0];
+ }
+ },
+ _onCaptureEsc: function(event) {
+ if (!this.noCancelOnEscKey) {
+ this.cancel(event);
+ }
+ },
+ _onCaptureTab: function(event) {
+ if (!this.withBackdrop) {
+ return;
+ }
+ var shift = event.shiftKey;
+ var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusableNode;
+ var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNode;
+ var shouldWrap = false;
+ if (nodeToCheck === nodeToSet) {
+ shouldWrap = true;
+ } else {
+ var focusedNode = this._manager.deepActiveElement;
+ shouldWrap = focusedNode === nodeToCheck || focusedNode === this;
+ }
+ if (shouldWrap) {
+ event.preventDefault();
+ this._focusedChild = nodeToSet;
+ this._applyFocus();
+ }
+ },
+ _onIronResize: function() {
+ if (this.opened && !this.__isAnimating) {
+ this.__onNextAnimationFrame(this.refit);
+ }
+ },
+ _onNodesChange: function() {
+ if (this.opened && !this.__isAnimating) {
+ this.notifyResize();
+ }
+ },
+ __openedChanged: function() {
+ if (this.opened) {
+ this._prepareRenderOpened();
+ this._manager.addOverlay(this);
+ this._applyFocus();
+ this._renderOpened();
+ } else {
+ this._manager.removeOverlay(this);
+ this._applyFocus();
+ this._renderClosed();
+ }
+ },
+ __onNextAnimationFrame: function(callback) {
+ if (this.__raf) {
+ window.cancelAnimationFrame(this.__raf);
+ }
+ var self = this;
+ this.__raf = window.requestAnimationFrame(function nextAnimationFrame() {
+ self.__raf = null;
+ callback.call(self);
+ });
+ }
+ };
+ Polymer.IronOverlayBehavior = [ Polymer.IronFitBehavior, Polymer.IronResizableBehavior, Polymer.IronOverlayBehaviorImpl ];
+})();
+
+(function() {
+ var metaDatas = {};
+ var metaArrays = {};
+ var singleton = null;
+ Polymer.IronMeta = Polymer({
+ is: 'iron-meta',
+ properties: {
+ type: {
+ type: String,
+ value: 'default',
+ observer: '_typeChanged'
},
key: {
type: String,
@@ -3000,19 +3197,27 @@ Polymer({
value: {
type: Object,
notify: true,
- readOnly: true
+ observer: '_valueChanged'
+ },
+ self: {
+ type: Boolean,
+ observer: '_selfChanged'
},
list: {
type: Array,
notify: true
}
},
+ hostAttributes: {
+ hidden: true
+ },
factoryImpl: function(config) {
if (config) {
for (var n in config) {
switch (n) {
case 'type':
case 'key':
+ case 'value':
this[n] = config[n];
break;
}
@@ -3023,3100 +3228,2975 @@ Polymer({
this._metaDatas = metaDatas;
this._metaArrays = metaArrays;
},
- _keyChanged: function(key) {
- this._setValue(this._metaData && this._metaData[key]);
+ _keyChanged: function(key, old) {
+ this._resetRegistration(old);
+ },
+ _valueChanged: function(value) {
+ this._resetRegistration(this.key);
+ },
+ _selfChanged: function(self) {
+ if (self) {
+ this.value = this;
+ }
},
_typeChanged: function(type) {
+ this._unregisterKey(this.key);
+ if (!metaDatas[type]) {
+ metaDatas[type] = {};
+ }
this._metaData = metaDatas[type];
- this.list = metaArrays[type];
- if (this.key) {
- this._keyChanged(this.key);
+ if (!metaArrays[type]) {
+ metaArrays[type] = [];
}
+ this.list = metaArrays[type];
+ this._registerKeyValue(this.key, this.value);
},
byKey: function(key) {
return this._metaData && this._metaData[key];
- }
- });
-})();
-
-Polymer({
- is: 'iron-icon',
- properties: {
- icon: {
- type: String,
- observer: '_iconChanged'
},
- theme: {
- type: String,
- observer: '_updateIcon'
+ _resetRegistration: function(oldKey) {
+ this._unregisterKey(oldKey);
+ this._registerKeyValue(this.key, this.value);
},
- src: {
- type: String,
- observer: '_srcChanged'
+ _unregisterKey: function(key) {
+ this._unregister(key, this._metaData, this.list);
},
- _meta: {
- value: Polymer.Base.create('iron-meta', {
- type: 'iconset'
- }),
- observer: '_updateIcon'
+ _registerKeyValue: function(key, value) {
+ this._register(key, value, this._metaData, this.list);
+ },
+ _register: function(key, value, data, list) {
+ if (key && data && value !== undefined) {
+ data[key] = value;
+ list.push(value);
+ }
+ },
+ _unregister: function(key, data, list) {
+ if (key && data) {
+ if (key in data) {
+ var value = data[key];
+ delete data[key];
+ this.arrayDelete(list, value);
+ }
+ }
}
- },
- _DEFAULT_ICONSET: 'icons',
- _iconChanged: function(icon) {
- var parts = (icon || '').split(':');
- this._iconName = parts.pop();
- this._iconsetName = parts.pop() || this._DEFAULT_ICONSET;
- this._updateIcon();
- },
- _srcChanged: function(src) {
- this._updateIcon();
- },
- _usesIconset: function() {
- return this.icon || !this.src;
- },
- _updateIcon: function() {
- if (this._usesIconset()) {
- if (this._img && this._img.parentNode) {
- Polymer.dom(this.root).removeChild(this._img);
+ });
+ Polymer.IronMeta.getIronMeta = function getIronMeta() {
+ if (singleton === null) {
+ singleton = new Polymer.IronMeta();
+ }
+ return singleton;
+ };
+ Polymer.IronMetaQuery = Polymer({
+ is: 'iron-meta-query',
+ properties: {
+ type: {
+ type: String,
+ value: 'default',
+ observer: '_typeChanged'
+ },
+ key: {
+ type: String,
+ observer: '_keyChanged'
+ },
+ value: {
+ type: Object,
+ notify: true,
+ readOnly: true
+ },
+ list: {
+ type: Array,
+ notify: true
}
- if (this._iconName === "") {
- if (this._iconset) {
- this._iconset.removeIcon(this);
- }
- } else if (this._iconsetName && this._meta) {
- this._iconset = this._meta.byKey(this._iconsetName);
- if (this._iconset) {
- this._iconset.applyIcon(this, this._iconName, this.theme);
- this.unlisten(window, 'iron-iconset-added', '_updateIcon');
- } else {
- this.listen(window, 'iron-iconset-added', '_updateIcon');
+ },
+ factoryImpl: function(config) {
+ if (config) {
+ for (var n in config) {
+ switch (n) {
+ case 'type':
+ case 'key':
+ this[n] = config[n];
+ break;
+ }
}
}
- } else {
- if (this._iconset) {
- this._iconset.removeIcon(this);
- }
- if (!this._img) {
- this._img = document.createElement('img');
- this._img.style.width = '100%';
- this._img.style.height = '100%';
- this._img.draggable = false;
+ },
+ created: function() {
+ this._metaDatas = metaDatas;
+ this._metaArrays = metaArrays;
+ },
+ _keyChanged: function(key) {
+ this._setValue(this._metaData && this._metaData[key]);
+ },
+ _typeChanged: function(type) {
+ this._metaData = metaDatas[type];
+ this.list = metaArrays[type];
+ if (this.key) {
+ this._keyChanged(this.key);
}
- this._img.src = this.src;
- Polymer.dom(this.root).appendChild(this._img);
- }
- }
-});
-
-Polymer.PaperInkyFocusBehaviorImpl = {
- observers: [ '_focusedChanged(receivedFocusFromKeyboard)' ],
- _focusedChanged: function(receivedFocusFromKeyboard) {
- if (receivedFocusFromKeyboard) {
- this.ensureRipple();
- }
- if (this.hasRipple()) {
- this._ripple.holdDown = receivedFocusFromKeyboard;
+ },
+ byKey: function(key) {
+ return this._metaData && this._metaData[key];
}
- },
- _createRipple: function() {
- var ripple = Polymer.PaperRippleBehavior._createRipple();
- ripple.id = 'ink';
- ripple.setAttribute('center', '');
- ripple.classList.add('circle');
- return ripple;
- }
-};
-
-Polymer.PaperInkyFocusBehavior = [ Polymer.IronButtonState, Polymer.IronControlState, Polymer.PaperRippleBehavior, Polymer.PaperInkyFocusBehaviorImpl ];
+ });
+})();
-Polymer({
- is: 'paper-icon-button',
- hostAttributes: {
- role: 'button',
- tabindex: '0'
- },
- behaviors: [ Polymer.PaperInkyFocusBehavior ],
+Polymer.NeonAnimatableBehavior = {
properties: {
- src: {
- type: String
+ animationConfig: {
+ type: Object
},
- icon: {
+ entryAnimation: {
+ observer: '_entryAnimationChanged',
type: String
},
- alt: {
- type: String,
- observer: "_altChanged"
- }
- },
- _altChanged: function(newValue, oldValue) {
- var label = this.getAttribute('aria-label');
- if (!label || oldValue == label) {
- this.setAttribute('aria-label', newValue);
- }
- }
-});
-
-Polymer({
- is: 'paper-tab',
- behaviors: [ Polymer.IronControlState, Polymer.IronButtonState, Polymer.PaperRippleBehavior ],
- properties: {
- link: {
- type: Boolean,
- value: false,
- reflectToAttribute: true
+ exitAnimation: {
+ observer: '_exitAnimationChanged',
+ type: String
}
},
- hostAttributes: {
- role: 'tab'
- },
- listeners: {
- down: '_updateNoink',
- tap: '_onTap'
+ _entryAnimationChanged: function() {
+ this.animationConfig = this.animationConfig || {};
+ this.animationConfig['entry'] = [ {
+ name: this.entryAnimation,
+ node: this
+ } ];
},
- attached: function() {
- this._updateNoink();
+ _exitAnimationChanged: function() {
+ this.animationConfig = this.animationConfig || {};
+ this.animationConfig['exit'] = [ {
+ name: this.exitAnimation,
+ node: this
+ } ];
},
- get _parentNoink() {
- var parent = Polymer.dom(this).parentNode;
- return !!parent && !!parent.noink;
+ _copyProperties: function(config1, config2) {
+ for (var property in config2) {
+ config1[property] = config2[property];
+ }
},
- _updateNoink: function() {
- this.noink = !!this.noink || !!this._parentNoink;
+ _cloneConfig: function(config) {
+ var clone = {
+ isClone: true
+ };
+ this._copyProperties(clone, config);
+ return clone;
},
- _onTap: function(event) {
- if (this.link) {
- var anchor = this.queryEffectiveChildren('a');
- if (!anchor) {
- return;
- }
- if (event.target === anchor) {
- return;
- }
- anchor.click();
+ _getAnimationConfigRecursive: function(type, map, allConfigs) {
+ if (!this.animationConfig) {
+ return;
}
- }
-});
-
-Polymer.IronMultiSelectableBehaviorImpl = {
- properties: {
- multi: {
- type: Boolean,
- value: false,
- observer: 'multiChanged'
- },
- selectedValues: {
- type: Array,
- notify: true
- },
- selectedItems: {
- type: Array,
- readOnly: true,
- notify: true
+ if (this.animationConfig.value && typeof this.animationConfig.value === 'function') {
+ this._warn(this._logf('playAnimation', "Please put 'animationConfig' inside of your components 'properties' object instead of outside of it."));
+ return;
}
- },
- observers: [ '_updateSelected(selectedValues.splices)' ],
- select: function(value) {
- if (this.multi) {
- if (this.selectedValues) {
- this._toggleSelected(value);
- } else {
- this.selectedValues = [ value ];
- }
+ var thisConfig;
+ if (type) {
+ thisConfig = this.animationConfig[type];
} else {
- this.selected = value;
+ thisConfig = this.animationConfig;
}
- },
- multiChanged: function(multi) {
- this._selection.multi = multi;
- },
- get _shouldUpdateSelection() {
- return this.selected != null || this.selectedValues != null && this.selectedValues.length;
- },
- _updateAttrForSelected: function() {
- if (!this.multi) {
- Polymer.IronSelectableBehavior._updateAttrForSelected.apply(this);
- } else if (this._shouldUpdateSelection) {
- this.selectedValues = this.selectedItems.map(function(selectedItem) {
- return this._indexToValue(this.indexOf(selectedItem));
- }, this).filter(function(unfilteredValue) {
- return unfilteredValue != null;
- }, this);
+ if (!Array.isArray(thisConfig)) {
+ thisConfig = [ thisConfig ];
}
- },
- _updateSelected: function() {
- if (this.multi) {
- this._selectMulti(this.selectedValues);
- } else {
- this._selectSelected(this.selected);
- }
- },
- _selectMulti: function(values) {
- if (values) {
- var selectedItems = this._valuesToItems(values);
- this._selection.clear(selectedItems);
- for (var i = 0; i < selectedItems.length; i++) {
- this._selection.setItemSelected(selectedItems[i], true);
- }
- if (this.fallbackSelection && this.items.length && !this._selection.get().length) {
- var fallback = this._valueToItem(this.fallbackSelection);
- if (fallback) {
- this.selectedValues = [ this.fallbackSelection ];
+ if (thisConfig) {
+ for (var config, index = 0; config = thisConfig[index]; index++) {
+ if (config.animatable) {
+ config.animatable._getAnimationConfigRecursive(config.type || type, map, allConfigs);
+ } else {
+ if (config.id) {
+ var cachedConfig = map[config.id];
+ if (cachedConfig) {
+ if (!cachedConfig.isClone) {
+ map[config.id] = this._cloneConfig(cachedConfig);
+ cachedConfig = map[config.id];
+ }
+ this._copyProperties(cachedConfig, config);
+ } else {
+ map[config.id] = config;
+ }
+ } else {
+ allConfigs.push(config);
+ }
}
}
- } else {
- this._selection.clear();
- }
- },
- _selectionChange: function() {
- var s = this._selection.get();
- if (this.multi) {
- this._setSelectedItems(s);
- } else {
- this._setSelectedItems([ s ]);
- this._setSelectedItem(s);
}
},
- _toggleSelected: function(value) {
- var i = this.selectedValues.indexOf(value);
- var unselected = i < 0;
- if (unselected) {
- this.push('selectedValues', value);
- } else {
- this.splice('selectedValues', i, 1);
+ getAnimationConfig: function(type) {
+ var map = {};
+ var allConfigs = [];
+ this._getAnimationConfigRecursive(type, map, allConfigs);
+ for (var key in map) {
+ allConfigs.push(map[key]);
}
- },
- _valuesToItems: function(values) {
- return values == null ? null : values.map(function(value) {
- return this._valueToItem(value);
- }, this);
+ return allConfigs;
}
};
-Polymer.IronMultiSelectableBehavior = [ Polymer.IronSelectableBehavior, Polymer.IronMultiSelectableBehaviorImpl ];
-
-Polymer.IronMenuBehaviorImpl = {
- properties: {
- focusedItem: {
- observer: '_focusedItemChanged',
- readOnly: true,
- type: Object
- },
- attrForItemTitle: {
- type: String
- }
- },
- hostAttributes: {
- role: 'menu',
- tabindex: '0'
- },
- observers: [ '_updateMultiselectable(multi)' ],
- listeners: {
- focus: '_onFocus',
- keydown: '_onKeydown',
- 'iron-items-changed': '_onIronItemsChanged'
- },
- keyBindings: {
- up: '_onUpKey',
- down: '_onDownKey',
- esc: '_onEscKey',
- 'shift+tab:keydown': '_onShiftTabDown'
- },
- attached: function() {
- this._resetTabindices();
- },
- select: function(value) {
- if (this._defaultFocusAsync) {
- this.cancelAsync(this._defaultFocusAsync);
- this._defaultFocusAsync = null;
- }
- var item = this._valueToItem(value);
- if (item && item.hasAttribute('disabled')) return;
- this._setFocusedItem(item);
- Polymer.IronMultiSelectableBehaviorImpl.select.apply(this, arguments);
- },
- _resetTabindices: function() {
- var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0] : this.selectedItem;
- this.items.forEach(function(item) {
- item.setAttribute('tabindex', item === selectedItem ? '0' : '-1');
- }, this);
- },
- _updateMultiselectable: function(multi) {
- if (multi) {
- this.setAttribute('aria-multiselectable', 'true');
- } else {
- this.removeAttribute('aria-multiselectable');
+Polymer.NeonAnimationRunnerBehaviorImpl = {
+ _configureAnimations: function(configs) {
+ var results = [];
+ if (configs.length > 0) {
+ for (var config, index = 0; config = configs[index]; index++) {
+ var neonAnimation = document.createElement(config.name);
+ if (neonAnimation.isNeonAnimation) {
+ var result = null;
+ try {
+ result = neonAnimation.configure(config);
+ if (typeof result.cancel != 'function') {
+ result = document.timeline.play(result);
+ }
+ } catch (e) {
+ result = null;
+ console.warn('Couldnt play', '(', config.name, ').', e);
+ }
+ if (result) {
+ results.push({
+ neonAnimation: neonAnimation,
+ config: config,
+ animation: result
+ });
+ }
+ } else {
+ console.warn(this.is + ':', config.name, 'not found!');
+ }
+ }
}
+ return results;
},
- _focusWithKeyboardEvent: function(event) {
- for (var i = 0, item; item = this.items[i]; i++) {
- var attr = this.attrForItemTitle || 'textContent';
- var title = item[attr] || item.getAttribute(attr);
- if (!item.hasAttribute('disabled') && title && title.trim().charAt(0).toLowerCase() === String.fromCharCode(event.keyCode).toLowerCase()) {
- this._setFocusedItem(item);
+ _shouldComplete: function(activeEntries) {
+ var finished = true;
+ for (var i = 0; i < activeEntries.length; i++) {
+ if (activeEntries[i].animation.playState != 'finished') {
+ finished = false;
break;
}
}
+ return finished;
},
- _focusPrevious: function() {
- var length = this.items.length;
- var curFocusIndex = Number(this.indexOf(this.focusedItem));
- for (var i = 1; i < length + 1; i++) {
- var item = this.items[(curFocusIndex - i + length) % length];
- if (!item.hasAttribute('disabled')) {
- var owner = Polymer.dom(item).getOwnerRoot() || document;
- this._setFocusedItem(item);
- if (Polymer.dom(owner).activeElement == item) {
- return;
- }
- }
+ _complete: function(activeEntries) {
+ for (var i = 0; i < activeEntries.length; i++) {
+ activeEntries[i].neonAnimation.complete(activeEntries[i].config);
+ }
+ for (var i = 0; i < activeEntries.length; i++) {
+ activeEntries[i].animation.cancel();
}
},
- _focusNext: function() {
- var length = this.items.length;
- var curFocusIndex = Number(this.indexOf(this.focusedItem));
- for (var i = 1; i < length + 1; i++) {
- var item = this.items[(curFocusIndex + i) % length];
- if (!item.hasAttribute('disabled')) {
- var owner = Polymer.dom(item).getOwnerRoot() || document;
- this._setFocusedItem(item);
- if (Polymer.dom(owner).activeElement == item) {
- return;
+ playAnimation: function(type, cookie) {
+ var configs = this.getAnimationConfig(type);
+ if (!configs) {
+ return;
+ }
+ this._active = this._active || {};
+ if (this._active[type]) {
+ this._complete(this._active[type]);
+ delete this._active[type];
+ }
+ var activeEntries = this._configureAnimations(configs);
+ if (activeEntries.length == 0) {
+ this.fire('neon-animation-finish', cookie, {
+ bubbles: false
+ });
+ return;
+ }
+ this._active[type] = activeEntries;
+ for (var i = 0; i < activeEntries.length; i++) {
+ activeEntries[i].animation.onfinish = function() {
+ if (this._shouldComplete(activeEntries)) {
+ this._complete(activeEntries);
+ delete this._active[type];
+ this.fire('neon-animation-finish', cookie, {
+ bubbles: false
+ });
}
- }
+ }.bind(this);
}
},
- _applySelection: function(item, isSelected) {
- if (isSelected) {
- item.setAttribute('aria-selected', 'true');
- } else {
- item.removeAttribute('aria-selected');
+ cancelAnimation: function() {
+ for (var k in this._animations) {
+ this._animations[k].cancel();
}
- Polymer.IronSelectableBehavior._applySelection.apply(this, arguments);
- },
- _focusedItemChanged: function(focusedItem, old) {
- old && old.setAttribute('tabindex', '-1');
- if (focusedItem) {
- focusedItem.setAttribute('tabindex', '0');
- focusedItem.focus();
+ this._animations = {};
+ }
+};
+
+Polymer.NeonAnimationRunnerBehavior = [ Polymer.NeonAnimatableBehavior, Polymer.NeonAnimationRunnerBehaviorImpl ];
+
+Polymer.NeonAnimationBehavior = {
+ properties: {
+ animationTiming: {
+ type: Object,
+ value: function() {
+ return {
+ duration: 500,
+ easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
+ fill: 'both'
+ };
+ }
}
},
- _onIronItemsChanged: function(event) {
- if (event.detail.addedNodes.length) {
- this._resetTabindices();
+ isNeonAnimation: true,
+ timingFromConfig: function(config) {
+ if (config.timing) {
+ for (var property in config.timing) {
+ this.animationTiming[property] = config.timing[property];
+ }
}
+ return this.animationTiming;
},
- _onShiftTabDown: function(event) {
- var oldTabIndex = this.getAttribute('tabindex');
- Polymer.IronMenuBehaviorImpl._shiftTabPressed = true;
- this._setFocusedItem(null);
- this.setAttribute('tabindex', '-1');
- this.async(function() {
- this.setAttribute('tabindex', oldTabIndex);
- Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
- }, 1);
- },
- _onFocus: function(event) {
- if (Polymer.IronMenuBehaviorImpl._shiftTabPressed) {
- return;
- }
- var rootTarget = Polymer.dom(event).rootTarget;
- if (rootTarget !== this && typeof rootTarget.tabIndex !== "undefined" && !this.isLightDescendant(rootTarget)) {
- return;
- }
- this._defaultFocusAsync = this.async(function() {
- var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0] : this.selectedItem;
- this._setFocusedItem(null);
- if (selectedItem) {
- this._setFocusedItem(selectedItem);
- } else if (this.items[0]) {
- this._focusNext();
- }
- });
- },
- _onUpKey: function(event) {
- this._focusPrevious();
- event.detail.keyboardEvent.preventDefault();
- },
- _onDownKey: function(event) {
- this._focusNext();
- event.detail.keyboardEvent.preventDefault();
- },
- _onEscKey: function(event) {
- this.focusedItem.blur();
- },
- _onKeydown: function(event) {
- if (!this.keyboardEventMatchesKeys(event, 'up down esc')) {
- this._focusWithKeyboardEvent(event);
- }
- event.stopPropagation();
- },
- _activateHandler: function(event) {
- Polymer.IronSelectableBehavior._activateHandler.call(this, event);
- event.stopPropagation();
- }
-};
-
-Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
-
-Polymer.IronMenuBehavior = [ Polymer.IronMultiSelectableBehavior, Polymer.IronA11yKeysBehavior, Polymer.IronMenuBehaviorImpl ];
-
-Polymer.IronMenubarBehaviorImpl = {
- hostAttributes: {
- role: 'menubar'
- },
- keyBindings: {
- left: '_onLeftKey',
- right: '_onRightKey'
- },
- _onUpKey: function(event) {
- this.focusedItem.click();
- event.detail.keyboardEvent.preventDefault();
- },
- _onDownKey: function(event) {
- this.focusedItem.click();
- event.detail.keyboardEvent.preventDefault();
- },
- get _isRTL() {
- return window.getComputedStyle(this)['direction'] === 'rtl';
- },
- _onLeftKey: function(event) {
- if (this._isRTL) {
- this._focusNext();
- } else {
- this._focusPrevious();
- }
- event.detail.keyboardEvent.preventDefault();
- },
- _onRightKey: function(event) {
- if (this._isRTL) {
- this._focusPrevious();
- } else {
- this._focusNext();
+ setPrefixedProperty: function(node, property, value) {
+ var map = {
+ transform: [ 'webkitTransform' ],
+ transformOrigin: [ 'mozTransformOrigin', 'webkitTransformOrigin' ]
+ };
+ var prefixes = map[property];
+ for (var prefix, index = 0; prefix = prefixes[index]; index++) {
+ node.style[prefix] = value;
}
- event.detail.keyboardEvent.preventDefault();
+ node.style[property] = value;
},
- _onKeydown: function(event) {
- if (this.keyboardEventMatchesKeys(event, 'up down left right esc')) {
- return;
- }
- this._focusWithKeyboardEvent(event);
- }
+ complete: function() {}
};
-Polymer.IronMenubarBehavior = [ Polymer.IronMenuBehavior, Polymer.IronMenubarBehaviorImpl ];
-
Polymer({
- is: 'iron-iconset-svg',
- properties: {
- name: {
- type: String,
- observer: '_nameChanged'
- },
- size: {
- type: Number,
- value: 24
- }
- },
- attached: function() {
- this.style.display = 'none';
- },
- getIconNames: function() {
- this._icons = this._createIconMap();
- return Object.keys(this._icons).map(function(n) {
- return this.name + ':' + n;
- }, this);
- },
- applyIcon: function(element, iconName) {
- element = element.root || element;
- this.removeIcon(element);
- var svg = this._cloneIcon(iconName);
- if (svg) {
- var pde = Polymer.dom(element);
- pde.insertBefore(svg, pde.childNodes[0]);
- return element._svgIcon = svg;
- }
- return null;
- },
- removeIcon: function(element) {
- if (element._svgIcon) {
- Polymer.dom(element).removeChild(element._svgIcon);
- element._svgIcon = null;
- }
- },
- _nameChanged: function() {
- new Polymer.IronMeta({
- type: 'iconset',
- key: this.name,
- value: this
- });
- this.async(function() {
- this.fire('iron-iconset-added', this, {
- node: window
- });
- });
- },
- _createIconMap: function() {
- var icons = Object.create(null);
- Polymer.dom(this).querySelectorAll('[id]').forEach(function(icon) {
- icons[icon.id] = icon;
- });
- return icons;
- },
- _cloneIcon: function(id) {
- this._icons = this._icons || this._createIconMap();
- return this._prepareSvgClone(this._icons[id], this.size);
+ is: 'opaque-animation',
+ behaviors: [ Polymer.NeonAnimationBehavior ],
+ configure: function(config) {
+ var node = config.node;
+ this._effect = new KeyframeEffect(node, [ {
+ opacity: '1'
+ }, {
+ opacity: '1'
+ } ], this.timingFromConfig(config));
+ node.style.opacity = '0';
+ return this._effect;
},
- _prepareSvgClone: function(sourceSvg, size) {
- if (sourceSvg) {
- var content = sourceSvg.cloneNode(true), svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'), viewBox = content.getAttribute('viewBox') || '0 0 ' + size + ' ' + size;
- svg.setAttribute('viewBox', viewBox);
- svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
- svg.style.cssText = 'pointer-events: none; display: block; width: 100%; height: 100%;';
- svg.appendChild(content).removeAttribute('id');
- return svg;
- }
- return null;
+ complete: function(config) {
+ config.node.style.opacity = '';
}
});
-Polymer({
- is: 'paper-tabs',
- behaviors: [ Polymer.IronResizableBehavior, Polymer.IronMenubarBehavior ],
- properties: {
- noink: {
- type: Boolean,
- value: false,
- observer: '_noinkChanged'
+(function() {
+ 'use strict';
+ var LAST_TOUCH_POSITION = {
+ pageX: 0,
+ pageY: 0
+ };
+ var ROOT_TARGET = null;
+ var SCROLLABLE_NODES = [];
+ Polymer.IronDropdownScrollManager = {
+ get currentLockingElement() {
+ return this._lockingElements[this._lockingElements.length - 1];
},
- noBar: {
- type: Boolean,
- value: false
+ elementIsScrollLocked: function(element) {
+ var currentLockingElement = this.currentLockingElement;
+ if (currentLockingElement === undefined) return false;
+ var scrollLocked;
+ if (this._hasCachedLockedElement(element)) {
+ return true;
+ }
+ if (this._hasCachedUnlockedElement(element)) {
+ return false;
+ }
+ scrollLocked = !!currentLockingElement && currentLockingElement !== element && !this._composedTreeContains(currentLockingElement, element);
+ if (scrollLocked) {
+ this._lockedElementCache.push(element);
+ } else {
+ this._unlockedElementCache.push(element);
+ }
+ return scrollLocked;
},
- noSlide: {
- type: Boolean,
- value: false
+ pushScrollLock: function(element) {
+ if (this._lockingElements.indexOf(element) >= 0) {
+ return;
+ }
+ if (this._lockingElements.length === 0) {
+ this._lockScrollInteractions();
+ }
+ this._lockingElements.push(element);
+ this._lockedElementCache = [];
+ this._unlockedElementCache = [];
},
- scrollable: {
- type: Boolean,
- value: false
+ removeScrollLock: function(element) {
+ var index = this._lockingElements.indexOf(element);
+ if (index === -1) {
+ return;
+ }
+ this._lockingElements.splice(index, 1);
+ this._lockedElementCache = [];
+ this._unlockedElementCache = [];
+ if (this._lockingElements.length === 0) {
+ this._unlockScrollInteractions();
+ }
},
- fitContainer: {
- type: Boolean,
- value: false
+ _lockingElements: [],
+ _lockedElementCache: null,
+ _unlockedElementCache: null,
+ _hasCachedLockedElement: function(element) {
+ return this._lockedElementCache.indexOf(element) > -1;
},
- disableDrag: {
- type: Boolean,
- value: false
+ _hasCachedUnlockedElement: function(element) {
+ return this._unlockedElementCache.indexOf(element) > -1;
},
- hideScrollButtons: {
- type: Boolean,
- value: false
+ _composedTreeContains: function(element, child) {
+ var contentElements;
+ var distributedNodes;
+ var contentIndex;
+ var nodeIndex;
+ if (element.contains(child)) {
+ return true;
+ }
+ contentElements = Polymer.dom(element).querySelectorAll('content');
+ for (contentIndex = 0; contentIndex < contentElements.length; ++contentIndex) {
+ distributedNodes = Polymer.dom(contentElements[contentIndex]).getDistributedNodes();
+ for (nodeIndex = 0; nodeIndex < distributedNodes.length; ++nodeIndex) {
+ if (this._composedTreeContains(distributedNodes[nodeIndex], child)) {
+ return true;
+ }
+ }
+ }
+ return false;
},
- alignBottom: {
- type: Boolean,
- value: false
+ _scrollInteractionHandler: function(event) {
+ if (event.cancelable && this._shouldPreventScrolling(event)) {
+ event.preventDefault();
+ }
+ if (event.targetTouches) {
+ var touch = event.targetTouches[0];
+ LAST_TOUCH_POSITION.pageX = touch.pageX;
+ LAST_TOUCH_POSITION.pageY = touch.pageY;
+ }
},
- selectable: {
- type: String,
- value: 'paper-tab'
+ _lockScrollInteractions: function() {
+ this._boundScrollHandler = this._boundScrollHandler || this._scrollInteractionHandler.bind(this);
+ document.addEventListener('wheel', this._boundScrollHandler, true);
+ document.addEventListener('mousewheel', this._boundScrollHandler, true);
+ document.addEventListener('DOMMouseScroll', this._boundScrollHandler, true);
+ document.addEventListener('touchstart', this._boundScrollHandler, true);
+ document.addEventListener('touchmove', this._boundScrollHandler, true);
},
- autoselect: {
- type: Boolean,
- value: false
+ _unlockScrollInteractions: function() {
+ document.removeEventListener('wheel', this._boundScrollHandler, true);
+ document.removeEventListener('mousewheel', this._boundScrollHandler, true);
+ document.removeEventListener('DOMMouseScroll', this._boundScrollHandler, true);
+ document.removeEventListener('touchstart', this._boundScrollHandler, true);
+ document.removeEventListener('touchmove', this._boundScrollHandler, true);
},
- autoselectDelay: {
- type: Number,
- value: 0
+ _shouldPreventScrolling: function(event) {
+ var target = Polymer.dom(event).rootTarget;
+ if (event.type !== 'touchmove' && ROOT_TARGET !== target) {
+ ROOT_TARGET = target;
+ SCROLLABLE_NODES = this._getScrollableNodes(Polymer.dom(event).path);
+ }
+ if (!SCROLLABLE_NODES.length) {
+ return true;
+ }
+ if (event.type === 'touchstart') {
+ return false;
+ }
+ var info = this._getScrollInfo(event);
+ return !this._getScrollingNode(SCROLLABLE_NODES, info.deltaX, info.deltaY);
},
- _step: {
- type: Number,
- value: 10
+ _getScrollableNodes: function(nodes) {
+ var scrollables = [];
+ var lockingIndex = nodes.indexOf(this.currentLockingElement);
+ for (var i = 0; i <= lockingIndex; i++) {
+ var node = nodes[i];
+ if (node.nodeType === 11) {
+ continue;
+ }
+ var style = node.style;
+ if (style.overflow !== 'scroll' && style.overflow !== 'auto') {
+ style = window.getComputedStyle(node);
+ }
+ if (style.overflow === 'scroll' || style.overflow === 'auto') {
+ scrollables.push(node);
+ }
+ }
+ return scrollables;
},
- _holdDelay: {
- type: Number,
- value: 1
+ _getScrollingNode: function(nodes, deltaX, deltaY) {
+ if (!deltaX && !deltaY) {
+ return;
+ }
+ var verticalScroll = Math.abs(deltaY) >= Math.abs(deltaX);
+ for (var i = 0; i < nodes.length; i++) {
+ var node = nodes[i];
+ var canScroll = false;
+ if (verticalScroll) {
+ canScroll = deltaY < 0 ? node.scrollTop > 0 : node.scrollTop < node.scrollHeight - node.clientHeight;
+ } else {
+ canScroll = deltaX < 0 ? node.scrollLeft > 0 : node.scrollLeft < node.scrollWidth - node.clientWidth;
+ }
+ if (canScroll) {
+ return node;
+ }
+ }
},
- _leftHidden: {
- type: Boolean,
- value: false
+ _getScrollInfo: function(event) {
+ var info = {
+ deltaX: event.deltaX,
+ deltaY: event.deltaY
+ };
+ if ('deltaX' in event) {} else if ('wheelDeltaX' in event) {
+ info.deltaX = -event.wheelDeltaX;
+ info.deltaY = -event.wheelDeltaY;
+ } else if ('axis' in event) {
+ info.deltaX = event.axis === 1 ? event.detail : 0;
+ info.deltaY = event.axis === 2 ? event.detail : 0;
+ } else if (event.targetTouches) {
+ var touch = event.targetTouches[0];
+ info.deltaX = LAST_TOUCH_POSITION.pageX - touch.pageX;
+ info.deltaY = LAST_TOUCH_POSITION.pageY - touch.pageY;
+ }
+ return info;
+ }
+ };
+})();
+
+(function() {
+ 'use strict';
+ Polymer({
+ is: 'iron-dropdown',
+ behaviors: [ Polymer.IronControlState, Polymer.IronA11yKeysBehavior, Polymer.IronOverlayBehavior, Polymer.NeonAnimationRunnerBehavior ],
+ properties: {
+ horizontalAlign: {
+ type: String,
+ value: 'left',
+ reflectToAttribute: true
+ },
+ verticalAlign: {
+ type: String,
+ value: 'top',
+ reflectToAttribute: true
+ },
+ openAnimationConfig: {
+ type: Object
+ },
+ closeAnimationConfig: {
+ type: Object
+ },
+ focusTarget: {
+ type: Object
+ },
+ noAnimations: {
+ type: Boolean,
+ value: false
+ },
+ allowOutsideScroll: {
+ type: Boolean,
+ value: false
+ },
+ _boundOnCaptureScroll: {
+ type: Function,
+ value: function() {
+ return this._onCaptureScroll.bind(this);
+ }
+ }
},
- _rightHidden: {
- type: Boolean,
- value: false
+ listeners: {
+ 'neon-animation-finish': '_onNeonAnimationFinish'
},
- _previousTab: {
- type: Object
- }
- },
- hostAttributes: {
- role: 'tablist'
- },
- listeners: {
- 'iron-resize': '_onTabSizingChanged',
- 'iron-items-changed': '_onTabSizingChanged',
- 'iron-select': '_onIronSelect',
- 'iron-deselect': '_onIronDeselect'
- },
- keyBindings: {
- 'left:keyup right:keyup': '_onArrowKeyup'
- },
- created: function() {
- this._holdJob = null;
- this._pendingActivationItem = undefined;
- this._pendingActivationTimeout = undefined;
- this._bindDelayedActivationHandler = this._delayedActivationHandler.bind(this);
- this.addEventListener('blur', this._onBlurCapture.bind(this), true);
- },
- ready: function() {
- this.setScrollDirection('y', this.$.tabsContainer);
- },
- detached: function() {
- this._cancelPendingActivation();
- },
- _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, fitContainer) {
- return scrollable ? 'scrollable' + (fitContainer ? ' fit-container' : '') : ' fit-container';
- },
- _computeSelectionBarClass: function(noBar, alignBottom) {
- if (noBar) {
- return 'hidden';
- } else if (alignBottom) {
- return 'align-bottom';
- }
- return '';
- },
- _onTabSizingChanged: function() {
- this.debounce('_onTabSizingChanged', 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);
- this._previousTab = null;
- }, 1);
- },
- _activateHandler: function() {
- this._cancelPendingActivation();
- Polymer.IronMenuBehaviorImpl._activateHandler.apply(this, arguments);
- },
- _scheduleActivation: function(item, delay) {
- this._pendingActivationItem = item;
- this._pendingActivationTimeout = this.async(this._bindDelayedActivationHandler, delay);
- },
- _delayedActivationHandler: function() {
- var item = this._pendingActivationItem;
- this._pendingActivationItem = undefined;
- this._pendingActivationTimeout = undefined;
- item.fire(this.activateEvent, null, {
- bubbles: true,
- cancelable: true
- });
- },
- _cancelPendingActivation: function() {
- if (this._pendingActivationTimeout !== undefined) {
- this.cancelAsync(this._pendingActivationTimeout);
- this._pendingActivationItem = undefined;
- this._pendingActivationTimeout = undefined;
- }
- },
- _onArrowKeyup: function(event) {
- if (this.autoselect) {
- this._scheduleActivation(this.focusedItem, this.autoselectDelay);
- }
- },
- _onBlurCapture: function(event) {
- if (event.target === this._pendingActivationItem) {
- this._cancelPendingActivation();
- }
- },
- get _tabContainerScrollSize() {
- return Math.max(0, this.$.tabsContainer.scrollWidth - this.$.tabsContainer.offsetWidth);
- },
- _scroll: function(e, detail) {
- if (!this.scrollable) {
- return;
- }
- var ddx = detail && -detail.ddx || 0;
- this._affectScroll(ddx);
- },
- _down: function(e) {
- 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.$.selectionBar.classList.remove('expand');
- this.$.selectionBar.classList.remove('contract');
- 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) {
- this.$.selectionBar.classList.remove('expand');
- this.$.selectionBar.classList.remove('contract');
- 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;
- this.$.selectionBar.classList.add('expand');
- var moveRight = oldIndex < index;
- var isRTL = this._isRTL;
- if (isRTL) {
- moveRight = !moveRight;
- }
- if (moveRight) {
- 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 {
- l += tabWidth - this.$.tabsContainer.offsetWidth;
- if (l > 0) {
- this.$.tabsContainer.scrollLeft += l;
- }
- }
- },
- _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('translateX(' + left + '%) scaleX(' + width / 100 + ')', this.$.selectionBar);
- },
- _onBarTransitionEnd: function(e) {
- var cl = this.$.selectionBar.classList;
- if (cl.contains('expand')) {
- cl.remove('expand');
- cl.add('contract');
- this._positionBar(this._pos.width, this._pos.left);
- } else if (cl.contains('contract')) {
- cl.remove('contract');
- }
- }
-});
-
-(function() {
- 'use strict';
- Polymer.IronA11yAnnouncer = Polymer({
- is: 'iron-a11y-announcer',
- properties: {
- mode: {
- type: String,
- value: 'polite'
- },
- _text: {
- type: String,
- value: ''
- }
+ observers: [ '_updateOverlayPosition(positionTarget, verticalAlign, horizontalAlign, verticalOffset, horizontalOffset)' ],
+ get containedElement() {
+ return Polymer.dom(this.$.content).getDistributedNodes()[0];
},
- created: function() {
- if (!Polymer.IronA11yAnnouncer.instance) {
- Polymer.IronA11yAnnouncer.instance = this;
- }
- document.body.addEventListener('iron-announce', this._onIronAnnounce.bind(this));
+ get _focusTarget() {
+ return this.focusTarget || this.containedElement;
},
- announce: function(text) {
- this._text = '';
- this.async(function() {
- this._text = text;
- }, 100);
+ ready: function() {
+ this._scrollTop = 0;
+ this._scrollLeft = 0;
+ this._refitOnScrollRAF = null;
},
- _onIronAnnounce: function(event) {
- if (event.detail && event.detail.text) {
- this.announce(event.detail.text);
+ attached: function() {
+ if (!this.sizingTarget || this.sizingTarget === this) {
+ this.sizingTarget = this.containedElement;
}
- }
- });
- Polymer.IronA11yAnnouncer.instance = null;
- Polymer.IronA11yAnnouncer.requestAvailability = function() {
- if (!Polymer.IronA11yAnnouncer.instance) {
- Polymer.IronA11yAnnouncer.instance = document.createElement('iron-a11y-announcer');
- }
- document.body.appendChild(Polymer.IronA11yAnnouncer.instance);
- };
-})();
-
-Polymer.IronValidatableBehaviorMeta = null;
-
-Polymer.IronValidatableBehavior = {
- properties: {
- validator: {
- type: String
},
- invalid: {
- notify: true,
- reflectToAttribute: true,
- type: Boolean,
- value: false
+ detached: function() {
+ this.cancelAnimation();
+ document.removeEventListener('scroll', this._boundOnCaptureScroll);
+ Polymer.IronDropdownScrollManager.removeScrollLock(this);
},
- _validatorMeta: {
- type: Object
+ _openedChanged: function() {
+ if (this.opened && this.disabled) {
+ this.cancel();
+ } else {
+ this.cancelAnimation();
+ this._updateAnimationConfig();
+ this._saveScrollPosition();
+ if (this.opened) {
+ document.addEventListener('scroll', this._boundOnCaptureScroll);
+ !this.allowOutsideScroll && Polymer.IronDropdownScrollManager.pushScrollLock(this);
+ } else {
+ document.removeEventListener('scroll', this._boundOnCaptureScroll);
+ Polymer.IronDropdownScrollManager.removeScrollLock(this);
+ }
+ Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this, arguments);
+ }
},
- validatorType: {
- type: String,
- value: 'validator'
+ _renderOpened: function() {
+ if (!this.noAnimations && this.animationConfig.open) {
+ this.$.contentWrapper.classList.add('animating');
+ this.playAnimation('open');
+ } else {
+ Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this, arguments);
+ }
},
- _validator: {
- type: Object,
- computed: '__computeValidator(validator)'
- }
- },
- observers: [ '_invalidChanged(invalid)' ],
- registered: function() {
- Polymer.IronValidatableBehaviorMeta = new Polymer.IronMeta({
- type: 'validator'
- });
- },
- _invalidChanged: function() {
- if (this.invalid) {
- this.setAttribute('aria-invalid', 'true');
- } else {
- this.removeAttribute('aria-invalid');
+ _renderClosed: function() {
+ if (!this.noAnimations && this.animationConfig.close) {
+ this.$.contentWrapper.classList.add('animating');
+ this.playAnimation('close');
+ } else {
+ Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this, arguments);
+ }
+ },
+ _onNeonAnimationFinish: function() {
+ this.$.contentWrapper.classList.remove('animating');
+ if (this.opened) {
+ this._finishRenderOpened();
+ } else {
+ this._finishRenderClosed();
+ }
+ },
+ _onCaptureScroll: function() {
+ if (!this.allowOutsideScroll) {
+ this._restoreScrollPosition();
+ } else {
+ this._refitOnScrollRAF && window.cancelAnimationFrame(this._refitOnScrollRAF);
+ this._refitOnScrollRAF = window.requestAnimationFrame(this.refit.bind(this));
+ }
+ },
+ _saveScrollPosition: function() {
+ if (document.scrollingElement) {
+ this._scrollTop = document.scrollingElement.scrollTop;
+ this._scrollLeft = document.scrollingElement.scrollLeft;
+ } else {
+ this._scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
+ this._scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
+ }
+ },
+ _restoreScrollPosition: function() {
+ if (document.scrollingElement) {
+ document.scrollingElement.scrollTop = this._scrollTop;
+ document.scrollingElement.scrollLeft = this._scrollLeft;
+ } else {
+ document.documentElement.scrollTop = this._scrollTop;
+ document.documentElement.scrollLeft = this._scrollLeft;
+ document.body.scrollTop = this._scrollTop;
+ document.body.scrollLeft = this._scrollLeft;
+ }
+ },
+ _updateAnimationConfig: function() {
+ var animations = (this.openAnimationConfig || []).concat(this.closeAnimationConfig || []);
+ for (var i = 0; i < animations.length; i++) {
+ animations[i].node = this.containedElement;
+ }
+ this.animationConfig = {
+ open: this.openAnimationConfig,
+ close: this.closeAnimationConfig
+ };
+ },
+ _updateOverlayPosition: function() {
+ if (this.isAttached) {
+ this.notifyResize();
+ }
+ },
+ _applyFocus: function() {
+ var focusTarget = this.focusTarget || this.containedElement;
+ if (focusTarget && this.opened && !this.noAutoFocus) {
+ focusTarget.focus();
+ } else {
+ Polymer.IronOverlayBehaviorImpl._applyFocus.apply(this, arguments);
+ }
+ }
+ });
+})();
+
+Polymer({
+ is: 'iron-icon',
+ properties: {
+ icon: {
+ type: String,
+ observer: '_iconChanged'
+ },
+ theme: {
+ type: String,
+ observer: '_updateIcon'
+ },
+ src: {
+ type: String,
+ observer: '_srcChanged'
+ },
+ _meta: {
+ value: Polymer.Base.create('iron-meta', {
+ type: 'iconset'
+ }),
+ observer: '_updateIcon'
}
},
- hasValidator: function() {
- return this._validator != null;
+ _DEFAULT_ICONSET: 'icons',
+ _iconChanged: function(icon) {
+ var parts = (icon || '').split(':');
+ this._iconName = parts.pop();
+ this._iconsetName = parts.pop() || this._DEFAULT_ICONSET;
+ this._updateIcon();
},
- validate: function(value) {
- this.invalid = !this._getValidity(value);
- return !this.invalid;
+ _srcChanged: function(src) {
+ this._updateIcon();
},
- _getValidity: function(value) {
- if (this.hasValidator()) {
- return this._validator.validate(value);
- }
- return true;
+ _usesIconset: function() {
+ return this.icon || !this.src;
},
- __computeValidator: function() {
- return Polymer.IronValidatableBehaviorMeta && Polymer.IronValidatableBehaviorMeta.byKey(this.validator);
+ _updateIcon: function() {
+ if (this._usesIconset()) {
+ if (this._img && this._img.parentNode) {
+ Polymer.dom(this.root).removeChild(this._img);
+ }
+ if (this._iconName === "") {
+ if (this._iconset) {
+ this._iconset.removeIcon(this);
+ }
+ } else if (this._iconsetName && this._meta) {
+ this._iconset = this._meta.byKey(this._iconsetName);
+ if (this._iconset) {
+ this._iconset.applyIcon(this, this._iconName, this.theme);
+ this.unlisten(window, 'iron-iconset-added', '_updateIcon');
+ } else {
+ this.listen(window, 'iron-iconset-added', '_updateIcon');
+ }
+ }
+ } else {
+ if (this._iconset) {
+ this._iconset.removeIcon(this);
+ }
+ if (!this._img) {
+ this._img = document.createElement('img');
+ this._img.style.width = '100%';
+ this._img.style.height = '100%';
+ this._img.draggable = false;
+ }
+ this._img.src = this.src;
+ Polymer.dom(this.root).appendChild(this._img);
+ }
}
-};
+});
-Polymer({
- is: 'iron-input',
- "extends": 'input',
- behaviors: [ Polymer.IronValidatableBehavior ],
+Polymer.IronButtonStateImpl = {
properties: {
- bindValue: {
- observer: '_bindValueChanged',
- type: String
- },
- preventInvalidInput: {
- type: Boolean
+ pressed: {
+ type: Boolean,
+ readOnly: true,
+ value: false,
+ reflectToAttribute: true,
+ observer: '_pressedChanged'
},
- allowedPattern: {
- type: String,
- observer: "_allowedPatternChanged"
+ toggles: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
},
- _previousValidInput: {
- type: String,
- value: ''
+ active: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ reflectToAttribute: true
},
- _patternAlreadyChecked: {
+ pointerDown: {
type: Boolean,
+ readOnly: true,
value: false
+ },
+ receivedFocusFromKeyboard: {
+ type: Boolean,
+ readOnly: true
+ },
+ ariaActiveAttribute: {
+ type: String,
+ value: 'aria-pressed',
+ observer: '_ariaActiveAttributeChanged'
}
},
listeners: {
- input: '_onInput',
- keypress: '_onKeypress'
- },
- registered: function() {
- if (!this._canDispatchEventOnDisabled()) {
- this._origDispatchEvent = this.dispatchEvent;
- this.dispatchEvent = this._dispatchEventFirefoxIE;
- }
- },
- created: function() {
- Polymer.IronA11yAnnouncer.requestAvailability();
- },
- _canDispatchEventOnDisabled: function() {
- var input = document.createElement('input');
- var canDispatch = false;
- input.disabled = true;
- input.addEventListener('feature-check-dispatch-event', function() {
- canDispatch = true;
- });
- try {
- input.dispatchEvent(new Event('feature-check-dispatch-event'));
- } catch (e) {}
- return canDispatch;
+ down: '_downHandler',
+ up: '_upHandler',
+ tap: '_tapHandler'
},
- _dispatchEventFirefoxIE: function() {
- var disabled = this.disabled;
- this.disabled = false;
- this._origDispatchEvent.apply(this, arguments);
- this.disabled = disabled;
+ observers: [ '_detectKeyboardFocus(focused)', '_activeChanged(active, ariaActiveAttribute)' ],
+ keyBindings: {
+ 'enter:keydown': '_asyncClick',
+ 'space:keydown': '_spaceKeyDownHandler',
+ 'space:keyup': '_spaceKeyUpHandler'
},
- get _patternRegExp() {
- var pattern;
- if (this.allowedPattern) {
- pattern = new RegExp(this.allowedPattern);
+ _mouseEventRe: /^mouse/,
+ _tapHandler: function() {
+ if (this.toggles) {
+ this._userActivate(!this.active);
} else {
- switch (this.type) {
- case 'number':
- pattern = /[0-9.,e-]/;
- break;
- }
+ this.active = false;
}
- return pattern;
},
- ready: function() {
- this.bindValue = this.value;
+ _detectKeyboardFocus: function(focused) {
+ this._setReceivedFocusFromKeyboard(!this.pointerDown && focused);
},
- _bindValueChanged: function() {
- if (this.value !== this.bindValue) {
- this.value = !(this.bindValue || this.bindValue === 0 || this.bindValue === false) ? '' : this.bindValue;
- }
- this.fire('bind-value-changed', {
- value: this.bindValue
- });
+ _userActivate: function(active) {
+ if (this.active !== active) {
+ this.active = active;
+ this.fire('change');
+ }
},
- _allowedPatternChanged: function() {
- this.preventInvalidInput = this.allowedPattern ? true : false;
+ _downHandler: function(event) {
+ this._setPointerDown(true);
+ this._setPressed(true);
+ this._setReceivedFocusFromKeyboard(false);
},
- _onInput: function() {
- if (this.preventInvalidInput && !this._patternAlreadyChecked) {
- var valid = this._checkPatternValidity();
- if (!valid) {
- this._announceInvalidCharacter('Invalid string of characters not entered.');
- this.value = this._previousValidInput;
- }
- }
- this.bindValue = this.value;
- this._previousValidInput = this.value;
- this._patternAlreadyChecked = false;
+ _upHandler: function() {
+ this._setPointerDown(false);
+ this._setPressed(false);
},
- _isPrintable: function(event) {
- var anyNonPrintable = event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 13 || event.keyCode == 27;
- var mozNonPrintable = event.keyCode == 19 || event.keyCode == 20 || event.keyCode == 45 || event.keyCode == 46 || event.keyCode == 144 || event.keyCode == 145 || event.keyCode > 32 && event.keyCode < 41 || event.keyCode > 111 && event.keyCode < 124;
- return !anyNonPrintable && !(event.charCode == 0 && mozNonPrintable);
+ _spaceKeyDownHandler: function(event) {
+ var keyboardEvent = event.detail.keyboardEvent;
+ var target = Polymer.dom(keyboardEvent).localTarget;
+ if (this.isLightDescendant(target)) return;
+ keyboardEvent.preventDefault();
+ keyboardEvent.stopImmediatePropagation();
+ this._setPressed(true);
},
- _onKeypress: function(event) {
- if (!this.preventInvalidInput && this.type !== 'number') {
- return;
- }
- var regexp = this._patternRegExp;
- if (!regexp) {
- return;
- }
- if (event.metaKey || event.ctrlKey || event.altKey) return;
- this._patternAlreadyChecked = true;
- var thisChar = String.fromCharCode(event.charCode);
- if (this._isPrintable(event) && !regexp.test(thisChar)) {
- event.preventDefault();
- this._announceInvalidCharacter('Invalid character ' + thisChar + ' not entered.');
+ _spaceKeyUpHandler: function(event) {
+ var keyboardEvent = event.detail.keyboardEvent;
+ var target = Polymer.dom(keyboardEvent).localTarget;
+ if (this.isLightDescendant(target)) return;
+ if (this.pressed) {
+ this._asyncClick();
}
+ this._setPressed(false);
},
- _checkPatternValidity: function() {
- var regexp = this._patternRegExp;
- if (!regexp) {
- return true;
+ _asyncClick: function() {
+ this.async(function() {
+ this.click();
+ }, 1);
+ },
+ _pressedChanged: function(pressed) {
+ this._changedButtonState();
+ },
+ _ariaActiveAttributeChanged: function(value, oldValue) {
+ if (oldValue && oldValue != value && this.hasAttribute(oldValue)) {
+ this.removeAttribute(oldValue);
}
- for (var i = 0; i < this.value.length; i++) {
- if (!regexp.test(this.value[i])) {
- return false;
- }
+ },
+ _activeChanged: function(active, ariaActiveAttribute) {
+ if (this.toggles) {
+ this.setAttribute(this.ariaActiveAttribute, active ? 'true' : 'false');
+ } else {
+ this.removeAttribute(this.ariaActiveAttribute);
}
- return true;
+ this._changedButtonState();
},
- validate: function() {
- var valid = this.checkValidity();
- if (valid) {
- if (this.required && this.value === '') {
- valid = false;
- } else if (this.hasValidator()) {
- valid = Polymer.IronValidatableBehavior.validate.call(this, this.value);
- }
+ _controlStateChanged: function() {
+ if (this.disabled) {
+ this._setPressed(false);
+ } else {
+ this._changedButtonState();
}
- this.invalid = !valid;
- this.fire('iron-input-validate');
- return valid;
},
- _announceInvalidCharacter: function(message) {
- this.fire('iron-announce', {
- text: message
- });
+ _changedButtonState: function() {
+ if (this._buttonStateChanged) {
+ this._buttonStateChanged();
+ }
}
-});
+};
-Polymer({
- is: 'paper-input-container',
- properties: {
- noLabelFloat: {
- type: Boolean,
- value: false
+Polymer.IronButtonState = [ Polymer.IronA11yKeysBehavior, Polymer.IronButtonStateImpl ];
+
+(function() {
+ var Utility = {
+ distance: function(x1, y1, x2, y2) {
+ var xDelta = x1 - x2;
+ var yDelta = y1 - y2;
+ return Math.sqrt(xDelta * xDelta + yDelta * yDelta);
},
- alwaysFloatLabel: {
- type: Boolean,
- value: false
+ now: window.performance && window.performance.now ? window.performance.now.bind(window.performance) : Date.now
+ };
+ 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();
},
- attrForValue: {
- type: String,
- value: 'bind-value'
+ 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);
+ }
+ };
+ function Ripple(element) {
+ this.element = element;
+ this.color = window.getComputedStyle(element).color;
+ 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);
+ this.resetInteractionState();
+ }
+ Ripple.MAX_RADIUS = 300;
+ Ripple.prototype = {
+ get recenters() {
+ return this.element.recenters;
},
- autoValidate: {
- type: Boolean,
- value: false
+ get center() {
+ return this.element.center;
},
- invalid: {
- observer: '_invalidChanged',
- type: Boolean,
- value: false
+ get mouseDownElapsed() {
+ var elapsed;
+ if (!this.mouseDownStart) {
+ return 0;
+ }
+ elapsed = Utility.now() - this.mouseDownStart;
+ if (this.mouseUpStart) {
+ elapsed -= this.mouseUpElapsed;
+ }
+ return elapsed;
},
- focused: {
- readOnly: true,
- type: Boolean,
- value: false,
- notify: true
+ get mouseUpElapsed() {
+ return this.mouseUpStart ? Utility.now() - this.mouseUpStart : 0;
},
- _addons: {
- type: Array
+ get mouseDownElapsedSeconds() {
+ return this.mouseDownElapsed / 1e3;
},
- _inputHasContent: {
- type: Boolean,
- value: false
+ get mouseUpElapsedSeconds() {
+ return this.mouseUpElapsed / 1e3;
},
- _inputSelector: {
- type: String,
- value: 'input,textarea,.paper-input-input'
+ get mouseInteractionSeconds() {
+ return this.mouseDownElapsedSeconds + this.mouseUpElapsedSeconds;
},
- _boundOnFocus: {
- type: Function,
- value: function() {
- return this._onFocus.bind(this);
- }
+ get initialOpacity() {
+ return this.element.initialOpacity;
},
- _boundOnBlur: {
- type: Function,
- value: function() {
- return this._onBlur.bind(this);
- }
+ get opacityDecayVelocity() {
+ return this.element.opacityDecayVelocity;
},
- _boundOnInput: {
- type: Function,
- value: function() {
- return this._onInput.bind(this);
- }
+ 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 - .2 * (waveRadius / Ripple.MAX_RADIUS);
+ var timeNow = this.mouseInteractionSeconds / duration;
+ var size = waveRadius * (1 - Math.pow(80, -timeNow));
+ return Math.abs(size);
},
- _boundValueChanged: {
- type: Function,
- value: function() {
- return this._onValueChanged.bind(this);
+ get opacity() {
+ if (!this.mouseUpStart) {
+ return this.initialOpacity;
}
- }
- },
- listeners: {
- 'addon-attached': '_onAddonAttached',
- 'iron-input-validate': '_onIronInputValidate'
- },
- get _valueChangedEvent() {
- return this.attrForValue + '-changed';
- },
- get _propertyForValue() {
- return Polymer.CaseMap.dashToCamelCase(this.attrForValue);
- },
- get _inputElement() {
- return Polymer.dom(this).querySelector(this._inputSelector);
- },
- get _inputElementValue() {
- return this._inputElement[this._propertyForValue] || this._inputElement.value;
- },
- ready: function() {
- if (!this._addons) {
- this._addons = [];
- }
- this.addEventListener('focus', this._boundOnFocus, true);
- this.addEventListener('blur', this._boundOnBlur, true);
- },
- attached: function() {
- if (this.attrForValue) {
- this._inputElement.addEventListener(this._valueChangedEvent, this._boundValueChanged);
- } else {
- this.addEventListener('input', this._onInput);
- }
- if (this._inputElementValue != '') {
- this._handleValueAndAutoValidate(this._inputElement);
- } else {
- this._handleValue(this._inputElement);
- }
- },
- _onAddonAttached: function(event) {
- if (!this._addons) {
- this._addons = [];
- }
- var target = event.target;
- if (this._addons.indexOf(target) === -1) {
- this._addons.push(target);
- if (this.isAttached) {
- this._handleValue(this._inputElement);
+ return Math.max(0, this.initialOpacity - this.mouseUpElapsedSeconds * this.opacityDecayVelocity);
+ },
+ get outerOpacity() {
+ var outerOpacity = this.mouseUpElapsedSeconds * .3;
+ var waveOpacity = this.opacity;
+ return Math.max(0, Math.min(outerOpacity, waveOpacity));
+ },
+ get isOpacityFullyDecayed() {
+ return this.opacity < .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;
+ },
+ get translationFraction() {
+ return Math.min(1, this.radius / this.containerMetrics.size * 2 / Math.sqrt(2));
+ },
+ get xNow() {
+ if (this.xEnd) {
+ return this.xStart + this.translationFraction * (this.xEnd - this.xStart);
}
- }
- },
- _onFocus: function() {
- this._setFocused(true);
- },
- _onBlur: function() {
- this._setFocused(false);
- this._handleValueAndAutoValidate(this._inputElement);
- },
- _onInput: function(event) {
- this._handleValueAndAutoValidate(event.target);
- },
- _onValueChanged: function(event) {
- this._handleValueAndAutoValidate(event.target);
- },
- _handleValue: function(inputElement) {
- var value = this._inputElementValue;
- if (value || value === 0 || inputElement.type === 'number' && !inputElement.checkValidity()) {
- this._inputHasContent = true;
- } else {
- this._inputHasContent = false;
- }
- this.updateAddons({
- inputElement: inputElement,
- value: value,
- invalid: this.invalid
- });
- },
- _handleValueAndAutoValidate: function(inputElement) {
- if (this.autoValidate) {
- var valid;
- if (inputElement.validate) {
- valid = inputElement.validate(this._inputElementValue);
- } else {
- valid = inputElement.checkValidity();
+ return this.xStart;
+ },
+ get yNow() {
+ if (this.yEnd) {
+ return this.yStart + this.translationFraction * (this.yEnd - this.yStart);
}
- this.invalid = !valid;
- }
- this._handleValue(inputElement);
- },
- _onIronInputValidate: function(event) {
- this.invalid = this._inputElement.invalid;
- },
- _invalidChanged: function() {
- if (this._addons) {
- this.updateAddons({
- invalid: this.invalid
- });
- }
- },
- updateAddons: function(state) {
- for (var addon, index = 0; addon = this._addons[index]; index++) {
- addon.update(state);
- }
- },
- _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused, invalid, _inputHasContent) {
- var cls = 'input-content';
- if (!noLabelFloat) {
- var label = this.querySelector('label');
- if (alwaysFloatLabel || _inputHasContent) {
- cls += ' label-is-floating';
- this.$.labelAndInputContainer.style.position = 'static';
- if (invalid) {
- cls += ' is-invalid';
- } else if (focused) {
- cls += " label-is-highlighted";
- }
+ 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;
+ 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)';
+ },
+ 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 {
- if (label) {
- this.$.labelAndInputContainer.style.position = 'relative';
- }
+ 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;
}
- } else {
- if (_inputHasContent) {
- cls += ' label-is-hidden';
+ if (this.recenters) {
+ this.xEnd = xCenter;
+ this.yEnd = yCenter;
+ this.slideDistance = Utility.distance(this.xStart, this.yStart, this.xEnd, this.yEnd);
}
- }
- return cls;
- },
- _computeUnderlineClass: function(focused, invalid) {
- var cls = 'underline';
- if (invalid) {
- cls += ' is-invalid';
- } else if (focused) {
- cls += ' is-highlighted';
- }
- return cls;
- },
- _computeAddOnContentClass: function(focused, invalid) {
- var cls = 'add-on-content';
- if (invalid) {
- cls += ' is-invalid';
- } else if (focused) {
- cls += ' is-highlighted';
- }
- return cls;
- }
-});
-
-Polymer.PaperSpinnerBehavior = {
- listeners: {
- animationend: '__reset',
- webkitAnimationEnd: '__reset'
- },
- properties: {
- active: {
- type: Boolean,
- value: false,
- reflectToAttribute: true,
- observer: '__activeChanged'
+ 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';
},
- alt: {
- type: String,
- value: 'loading',
- observer: '__altChanged'
+ upAction: function(event) {
+ if (!this.isMouseDown) {
+ return;
+ }
+ this.mouseUpStart = Utility.now();
},
- __coolingDown: {
- type: Boolean,
- value: false
- }
- },
- __computeContainerClasses: function(active, coolingDown) {
- return [ active || coolingDown ? 'active' : '', coolingDown ? 'cooldown' : '' ].join(' ');
- },
- __activeChanged: function(active, old) {
- this.__setAriaHidden(!active);
- this.__coolingDown = !active && old;
- },
- __altChanged: function(alt) {
- if (alt === this.getPropertyInfo('alt').value) {
- this.alt = this.getAttribute('aria-label') || alt;
- } else {
- this.__setAriaHidden(alt === '');
- this.setAttribute('aria-label', alt);
- }
- },
- __setAriaHidden: function(hidden) {
- var attr = 'aria-hidden';
- if (hidden) {
- this.setAttribute(attr, 'true');
- } else {
- this.removeAttribute(attr);
+ remove: function() {
+ Polymer.dom(this.waveContainer.parentNode).removeChild(this.waveContainer);
}
- },
- __reset: function() {
- this.active = false;
- this.__coolingDown = false;
- }
-};
-
-Polymer({
- is: 'paper-spinner-lite',
- behaviors: [ Polymer.PaperSpinnerBehavior ]
-});
-
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-var CrSearchFieldBehavior = {
- properties: {
- label: {
- type: String,
- value: ''
+ };
+ Polymer({
+ is: 'paper-ripple',
+ behaviors: [ Polymer.IronA11yKeysBehavior ],
+ properties: {
+ initialOpacity: {
+ type: Number,
+ value: .25
+ },
+ opacityDecayVelocity: {
+ type: Number,
+ value: .8
+ },
+ recenters: {
+ type: Boolean,
+ value: false
+ },
+ center: {
+ type: Boolean,
+ value: false
+ },
+ ripples: {
+ type: Array,
+ value: function() {
+ return [];
+ }
+ },
+ animating: {
+ type: Boolean,
+ readOnly: true,
+ reflectToAttribute: true,
+ value: false
+ },
+ holdDown: {
+ type: Boolean,
+ value: false,
+ observer: '_holdDownChanged'
+ },
+ noink: {
+ type: Boolean,
+ value: false
+ },
+ _animating: {
+ type: Boolean
+ },
+ _boundAnimate: {
+ type: Function,
+ value: function() {
+ return this.animate.bind(this);
+ }
+ }
},
- clearLabel: {
- type: String,
- value: ''
+ get target() {
+ return this.keyEventTarget;
},
- showingSearch: {
+ keyBindings: {
+ 'enter:keydown': '_onEnterKeydown',
+ 'space:keydown': '_onSpaceKeydown',
+ 'space:keyup': '_onSpaceKeyup'
+ },
+ attached: function() {
+ if (this.parentNode.nodeType == 11) {
+ this.keyEventTarget = Polymer.dom(this).getOwnerRoot().host;
+ } else {
+ this.keyEventTarget = this.parentNode;
+ }
+ var keyEventTarget = this.keyEventTarget;
+ this.listen(keyEventTarget, 'up', 'uiUpAction');
+ this.listen(keyEventTarget, 'down', 'uiDownAction');
+ },
+ detached: function() {
+ this.unlisten(this.keyEventTarget, 'up', 'uiUpAction');
+ this.unlisten(this.keyEventTarget, 'down', 'uiDownAction');
+ this.keyEventTarget = null;
+ },
+ get shouldKeepAnimating() {
+ for (var index = 0; index < this.ripples.length; ++index) {
+ if (!this.ripples[index].isAnimationComplete) {
+ return true;
+ }
+ }
+ return false;
+ },
+ simulatedRipple: function() {
+ this.downAction(null);
+ this.async(function() {
+ this.upAction();
+ }, 1);
+ },
+ uiDownAction: function(event) {
+ if (!this.noink) {
+ this.downAction(event);
+ }
+ },
+ downAction: function(event) {
+ if (this.holdDown && this.ripples.length > 0) {
+ return;
+ }
+ var ripple = this.addRipple();
+ ripple.downAction(event);
+ if (!this._animating) {
+ this._animating = true;
+ this.animate();
+ }
+ },
+ uiUpAction: function(event) {
+ if (!this.noink) {
+ this.upAction(event);
+ }
+ },
+ upAction: function(event) {
+ if (this.holdDown) {
+ return;
+ }
+ this.ripples.forEach(function(ripple) {
+ ripple.upAction(event);
+ });
+ this._animating = true;
+ this.animate();
+ },
+ onAnimationComplete: function() {
+ this._animating = false;
+ this.$.background.style.backgroundColor = null;
+ this.fire('transitionend');
+ },
+ addRipple: function() {
+ var ripple = new Ripple(this);
+ Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);
+ this.$.background.style.backgroundColor = ripple.color;
+ this.ripples.push(ripple);
+ this._setAnimating(true);
+ return ripple;
+ },
+ removeRipple: function(ripple) {
+ var rippleIndex = this.ripples.indexOf(ripple);
+ if (rippleIndex < 0) {
+ return;
+ }
+ this.ripples.splice(rippleIndex, 1);
+ ripple.remove();
+ if (!this.ripples.length) {
+ this._setAnimating(false);
+ }
+ },
+ animate: function() {
+ if (!this._animating) {
+ return;
+ }
+ var index;
+ var ripple;
+ for (index = 0; index < this.ripples.length; ++index) {
+ ripple = this.ripples[index];
+ ripple.draw();
+ this.$.background.style.opacity = ripple.outerOpacity;
+ if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) {
+ this.removeRipple(ripple);
+ }
+ }
+ if (!this.shouldKeepAnimating && this.ripples.length === 0) {
+ this.onAnimationComplete();
+ } else {
+ window.requestAnimationFrame(this._boundAnimate);
+ }
+ },
+ _onEnterKeydown: function() {
+ this.uiDownAction();
+ this.async(this.uiUpAction, 1);
+ },
+ _onSpaceKeydown: function() {
+ this.uiDownAction();
+ },
+ _onSpaceKeyup: function() {
+ this.uiUpAction();
+ },
+ _holdDownChanged: function(newVal, oldVal) {
+ if (oldVal === undefined) {
+ return;
+ }
+ if (newVal) {
+ this.downAction();
+ } else {
+ this.upAction();
+ }
+ }
+ });
+})();
+
+Polymer.PaperRippleBehavior = {
+ properties: {
+ noink: {
type: Boolean,
- value: false,
- notify: true,
- observer: 'showingSearchChanged_',
- reflectToAttribute: true
+ observer: '_noinkChanged'
},
- lastValue_: {
- type: String,
- value: ''
+ _rippleContainer: {
+ type: Object
}
},
- getSearchInput: function() {},
- getValue: function() {
- return this.getSearchInput().value;
+ _buttonStateChanged: function() {
+ if (this.focused) {
+ this.ensureRipple();
+ }
},
- setValue: function(value) {
- this.getSearchInput().bindValue = value;
- this.onValueChanged_(value);
+ _downHandler: function(event) {
+ Polymer.IronButtonStateImpl._downHandler.call(this, event);
+ if (this.pressed) {
+ this.ensureRipple(event);
+ }
},
- showAndFocus: function() {
- this.showingSearch = true;
- this.focus_();
+ ensureRipple: function(optTriggeringEvent) {
+ if (!this.hasRipple()) {
+ this._ripple = this._createRipple();
+ this._ripple.noink = this.noink;
+ var rippleContainer = this._rippleContainer || this.root;
+ if (rippleContainer) {
+ Polymer.dom(rippleContainer).appendChild(this._ripple);
+ }
+ if (optTriggeringEvent) {
+ var domContainer = Polymer.dom(this._rippleContainer || this);
+ var target = Polymer.dom(optTriggeringEvent).rootTarget;
+ if (domContainer.deepContains(target)) {
+ this._ripple.uiDownAction(optTriggeringEvent);
+ }
+ }
+ }
},
- focus_: function() {
- this.getSearchInput().focus();
+ getRipple: function() {
+ this.ensureRipple();
+ return this._ripple;
},
- onSearchTermSearch: function() {
- this.onValueChanged_(this.getValue());
- },
- onValueChanged_: function(newValue) {
- if (newValue == this.lastValue_) return;
- this.fire('search-changed', newValue);
- this.lastValue_ = newValue;
+ hasRipple: function() {
+ return Boolean(this._ripple);
},
- onSearchTermKeydown: function(e) {
- if (e.key == 'Escape') this.showingSearch = false;
+ _createRipple: function() {
+ return document.createElement('paper-ripple');
},
- showingSearchChanged_: function() {
- if (this.showingSearch) {
- this.focus_();
- return;
+ _noinkChanged: function(noink) {
+ if (this.hasRipple()) {
+ this._ripple.noink = noink;
}
- this.setValue('');
- this.getSearchInput().blur();
}
};
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Polymer({
- is: 'cr-toolbar-search-field',
- behaviors: [ CrSearchFieldBehavior ],
+Polymer.PaperButtonBehaviorImpl = {
properties: {
- narrow: {
- type: Boolean,
- reflectToAttribute: true
- },
- label: String,
- clearLabel: String,
- spinnerActive: {
- type: Boolean,
- reflectToAttribute: true
- },
- hasSearchText_: Boolean,
- isSpinnerShown_: {
- type: Boolean,
- computed: 'computeIsSpinnerShown_(spinnerActive, showingSearch)'
+ elevation: {
+ type: Number,
+ reflectToAttribute: true,
+ readOnly: true
}
},
- listeners: {
- tap: 'showSearch_',
- 'searchInput.bind-value-changed': 'onBindValueChanged_'
+ observers: [ '_calculateElevation(focused, disabled, active, pressed, receivedFocusFromKeyboard)', '_computeKeyboardClass(receivedFocusFromKeyboard)' ],
+ hostAttributes: {
+ role: 'button',
+ tabindex: '0',
+ animated: true
},
- getSearchInput: function() {
- return this.$.searchInput;
+ _calculateElevation: function() {
+ var e = 1;
+ if (this.disabled) {
+ e = 0;
+ } else if (this.active || this.pressed) {
+ e = 4;
+ } else if (this.receivedFocusFromKeyboard) {
+ e = 3;
+ }
+ this._setElevation(e);
},
- isSearchFocused: function() {
- return this.$.searchTerm.focused;
+ _computeKeyboardClass: function(receivedFocusFromKeyboard) {
+ this.toggleClass('keyboard-focus', receivedFocusFromKeyboard);
},
- computeIconTabIndex_: function(narrow) {
- return narrow ? 0 : -1;
+ _spaceKeyDownHandler: function(event) {
+ Polymer.IronButtonStateImpl._spaceKeyDownHandler.call(this, event);
+ if (this.hasRipple() && this.getRipple().ripples.length < 1) {
+ this._ripple.uiDownAction();
+ }
},
- computeIsSpinnerShown_: function() {
- return this.spinnerActive && this.showingSearch;
+ _spaceKeyUpHandler: function(event) {
+ Polymer.IronButtonStateImpl._spaceKeyUpHandler.call(this, event);
+ if (this.hasRipple()) {
+ this._ripple.uiUpAction();
+ }
+ }
+};
+
+Polymer.PaperButtonBehavior = [ Polymer.IronButtonState, Polymer.IronControlState, Polymer.PaperRippleBehavior, Polymer.PaperButtonBehaviorImpl ];
+
+Polymer({
+ is: 'paper-button',
+ behaviors: [ Polymer.PaperButtonBehavior ],
+ properties: {
+ raised: {
+ type: Boolean,
+ reflectToAttribute: true,
+ value: false,
+ observer: '_calculateElevation'
+ }
},
- onInputBlur_: function() {
- if (!this.hasSearchText_) this.showingSearch = false;
+ _calculateElevation: function() {
+ if (!this.raised) {
+ this._setElevation(0);
+ } else {
+ Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this);
+ }
+ }
+});
+
+Polymer({
+ is: 'paper-icon-button-light',
+ "extends": 'button',
+ behaviors: [ Polymer.PaperRippleBehavior ],
+ listeners: {
+ down: '_rippleDown',
+ up: '_rippleUp',
+ focus: '_rippleDown',
+ blur: '_rippleUp'
},
- onBindValueChanged_: function() {
- var newValue = this.$.searchInput.bindValue;
- this.hasSearchText_ = newValue != '';
- if (newValue != '') this.showingSearch = true;
+ _rippleDown: function() {
+ this.getRipple().downAction();
},
- showSearch_: function(e) {
- if (e.target != this.$.clearSearch) this.showingSearch = true;
+ _rippleUp: function() {
+ this.getRipple().upAction();
},
- hideSearch_: function(e) {
- this.showingSearch = false;
- e.stopPropagation();
+ ensureRipple: function(var_args) {
+ var lastRipple = this._ripple;
+ Polymer.PaperRippleBehavior.ensureRipple.apply(this, arguments);
+ if (this._ripple && this._ripple !== lastRipple) {
+ this._ripple.center = true;
+ this._ripple.classList.add('circle');
+ }
}
});
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
+Polymer.PaperInkyFocusBehaviorImpl = {
+ observers: [ '_focusedChanged(receivedFocusFromKeyboard)' ],
+ _focusedChanged: function(receivedFocusFromKeyboard) {
+ if (receivedFocusFromKeyboard) {
+ this.ensureRipple();
+ }
+ if (this.hasRipple()) {
+ this._ripple.holdDown = receivedFocusFromKeyboard;
+ }
+ },
+ _createRipple: function() {
+ var ripple = Polymer.PaperRippleBehavior._createRipple();
+ ripple.id = 'ink';
+ ripple.setAttribute('center', '');
+ ripple.classList.add('circle');
+ return ripple;
+ }
+};
+
+Polymer.PaperInkyFocusBehavior = [ Polymer.IronButtonState, Polymer.IronControlState, Polymer.PaperRippleBehavior, Polymer.PaperInkyFocusBehaviorImpl ];
+
Polymer({
- is: 'cr-toolbar',
+ is: 'paper-icon-button',
+ hostAttributes: {
+ role: 'button',
+ tabindex: '0'
+ },
+ behaviors: [ Polymer.PaperInkyFocusBehavior ],
properties: {
- pageName: String,
- searchPrompt: String,
- clearLabel: String,
- menuLabel: String,
- spinnerActive: Boolean,
- showMenu: {
- type: Boolean,
- value: false
+ src: {
+ type: String
},
- narrow_: {
- type: Boolean,
- reflectToAttribute: true
+ icon: {
+ type: String
},
- showingSearch_: {
+ alt: {
+ type: String,
+ observer: "_altChanged"
+ }
+ },
+ _altChanged: function(newValue, oldValue) {
+ var label = this.getAttribute('aria-label');
+ if (!label || oldValue == label) {
+ this.setAttribute('aria-label', newValue);
+ }
+ }
+});
+
+Polymer({
+ is: 'paper-tab',
+ behaviors: [ Polymer.IronControlState, Polymer.IronButtonState, Polymer.PaperRippleBehavior ],
+ properties: {
+ link: {
type: Boolean,
+ value: false,
reflectToAttribute: true
}
},
- getSearchField: function() {
- return this.$.search;
+ hostAttributes: {
+ role: 'tab'
},
- onMenuTap_: function(e) {
- this.fire('cr-menu-tap');
+ listeners: {
+ down: '_updateNoink',
+ tap: '_onTap'
+ },
+ attached: function() {
+ this._updateNoink();
+ },
+ get _parentNoink() {
+ var parent = Polymer.dom(this).parentNode;
+ return !!parent && !!parent.noink;
+ },
+ _updateNoink: function() {
+ this.noink = !!this.noink || !!this._parentNoink;
+ },
+ _onTap: function(event) {
+ if (this.link) {
+ var anchor = this.queryEffectiveChildren('a');
+ if (!anchor) {
+ return;
+ }
+ if (event.target === anchor) {
+ return;
+ }
+ anchor.click();
+ }
}
});
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Polymer({
- is: 'history-toolbar',
+Polymer.IronMultiSelectableBehaviorImpl = {
properties: {
- count: {
- type: Number,
- value: 0,
- observer: 'changeToolbarView_'
- },
- itemsSelected_: {
+ multi: {
type: Boolean,
value: false,
- reflectToAttribute: true
+ observer: 'multiChanged'
},
- searchTerm: {
- type: String,
+ selectedValues: {
+ type: Array,
notify: true
},
- spinnerActive: {
- type: Boolean,
- value: false
- },
- hasDrawer: {
- type: Boolean,
- observer: 'hasDrawerChanged_',
- reflectToAttribute: true
- },
- isGroupedMode: {
- type: Boolean,
- reflectToAttribute: true
- },
- groupedRange: {
- type: Number,
- value: 0,
- reflectToAttribute: true,
+ selectedItems: {
+ type: Array,
+ readOnly: true,
notify: true
- },
- queryStartTime: String,
- queryEndTime: String
- },
- changeToolbarView_: function() {
- this.itemsSelected_ = this.count > 0;
- },
- setSearchTerm: function(search) {
- if (this.searchTerm == search) return;
- this.searchTerm = search;
- var searchField = this.$['main-toolbar'].getSearchField();
- searchField.showAndFocus();
- searchField.setValue(search);
+ }
},
- onSearchChanged_: function(event) {
- this.searchTerm = event.detail;
+ observers: [ '_updateSelected(selectedValues.splices)' ],
+ select: function(value) {
+ if (this.multi) {
+ if (this.selectedValues) {
+ this._toggleSelected(value);
+ } else {
+ this.selectedValues = [ value ];
+ }
+ } else {
+ this.selected = value;
+ }
},
- onClearSelectionTap_: function() {
- this.fire('unselect-all');
+ multiChanged: function(multi) {
+ this._selection.multi = multi;
},
- onDeleteTap_: function() {
- this.fire('delete-selected');
+ get _shouldUpdateSelection() {
+ return this.selected != null || this.selectedValues != null && this.selectedValues.length;
},
- get searchBar() {
- return this.$['main-toolbar'].getSearchField();
+ _updateAttrForSelected: function() {
+ if (!this.multi) {
+ Polymer.IronSelectableBehavior._updateAttrForSelected.apply(this);
+ } else if (this._shouldUpdateSelection) {
+ this.selectedValues = this.selectedItems.map(function(selectedItem) {
+ return this._indexToValue(this.indexOf(selectedItem));
+ }, this).filter(function(unfilteredValue) {
+ return unfilteredValue != null;
+ }, this);
+ }
},
- showSearchField: function() {
- this.$['main-toolbar'].getSearchField().showAndFocus();
+ _updateSelected: function() {
+ if (this.multi) {
+ this._selectMulti(this.selectedValues);
+ } else {
+ this._selectSelected(this.selected);
+ }
},
- deletingAllowed_: function() {
- return loadTimeData.getBoolean('allowDeletingHistory');
+ _selectMulti: function(values) {
+ if (values) {
+ var selectedItems = this._valuesToItems(values);
+ this._selection.clear(selectedItems);
+ for (var i = 0; i < selectedItems.length; i++) {
+ this._selection.setItemSelected(selectedItems[i], true);
+ }
+ if (this.fallbackSelection && this.items.length && !this._selection.get().length) {
+ var fallback = this._valueToItem(this.fallbackSelection);
+ if (fallback) {
+ this.selectedValues = [ this.fallbackSelection ];
+ }
+ }
+ } else {
+ this._selection.clear();
+ }
},
- numberOfItemsSelected_: function(count) {
- return count > 0 ? loadTimeData.getStringF('itemsSelected', count) : '';
+ _selectionChange: function() {
+ var s = this._selection.get();
+ if (this.multi) {
+ this._setSelectedItems(s);
+ } else {
+ this._setSelectedItems([ s ]);
+ this._setSelectedItem(s);
+ }
},
- getHistoryInterval_: function(queryStartTime, queryEndTime) {
- return loadTimeData.getStringF('historyInterval', queryStartTime, queryEndTime);
+ _toggleSelected: function(value) {
+ var i = this.selectedValues.indexOf(value);
+ var unselected = i < 0;
+ if (unselected) {
+ this.push('selectedValues', value);
+ } else {
+ this.splice('selectedValues', i, 1);
+ }
},
- hasDrawerChanged_: function() {
- this.updateStyles();
+ _valuesToItems: function(values) {
+ return values == null ? null : values.map(function(value) {
+ return this._valueToItem(value);
+ }, this);
}
-});
+};
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Polymer({
- is: 'cr-dialog',
- "extends": 'dialog',
- created: function() {
- window.addEventListener('popstate', function() {
- if (this.open) this.cancel();
- }.bind(this));
- },
- cancel: function() {
- this.fire('cancel');
- HTMLDialogElement.prototype.close.call(this, '');
- },
- close: function(opt_returnValue) {
- HTMLDialogElement.prototype.close.call(this, 'success');
- },
- getCloseButton: function() {
- return this.$.close;
- }
-});
+Polymer.IronMultiSelectableBehavior = [ Polymer.IronSelectableBehavior, Polymer.IronMultiSelectableBehaviorImpl ];
-Polymer.IronFitBehavior = {
+Polymer.IronMenuBehaviorImpl = {
properties: {
- sizingTarget: {
- type: Object,
- value: function() {
- return this;
- }
- },
- fitInto: {
- type: Object,
- value: window
- },
- noOverlap: {
- type: Boolean
- },
- positionTarget: {
- type: Element
- },
- horizontalAlign: {
- type: String
+ focusedItem: {
+ observer: '_focusedItemChanged',
+ readOnly: true,
+ type: Object
},
- verticalAlign: {
+ attrForItemTitle: {
type: String
- },
- dynamicAlign: {
- type: Boolean
- },
- horizontalOffset: {
- type: Number,
- value: 0,
- notify: true
- },
- verticalOffset: {
- type: Number,
- value: 0,
- notify: true
- },
- autoFitOnAttach: {
- type: Boolean,
- value: false
- },
- _fitInfo: {
- type: Object
}
},
- get _fitWidth() {
- var fitWidth;
- if (this.fitInto === window) {
- fitWidth = this.fitInto.innerWidth;
- } else {
- fitWidth = this.fitInto.getBoundingClientRect().width;
- }
- return fitWidth;
+ hostAttributes: {
+ role: 'menu',
+ tabindex: '0'
},
- get _fitHeight() {
- var fitHeight;
- if (this.fitInto === window) {
- fitHeight = this.fitInto.innerHeight;
- } else {
- fitHeight = this.fitInto.getBoundingClientRect().height;
- }
- return fitHeight;
+ observers: [ '_updateMultiselectable(multi)' ],
+ listeners: {
+ focus: '_onFocus',
+ keydown: '_onKeydown',
+ 'iron-items-changed': '_onIronItemsChanged'
},
- get _fitLeft() {
- var fitLeft;
- if (this.fitInto === window) {
- fitLeft = 0;
- } else {
- fitLeft = this.fitInto.getBoundingClientRect().left;
+ keyBindings: {
+ up: '_onUpKey',
+ down: '_onDownKey',
+ esc: '_onEscKey',
+ 'shift+tab:keydown': '_onShiftTabDown'
+ },
+ attached: function() {
+ this._resetTabindices();
+ },
+ select: function(value) {
+ if (this._defaultFocusAsync) {
+ this.cancelAsync(this._defaultFocusAsync);
+ this._defaultFocusAsync = null;
}
- return fitLeft;
+ var item = this._valueToItem(value);
+ if (item && item.hasAttribute('disabled')) return;
+ this._setFocusedItem(item);
+ Polymer.IronMultiSelectableBehaviorImpl.select.apply(this, arguments);
},
- get _fitTop() {
- var fitTop;
- if (this.fitInto === window) {
- fitTop = 0;
+ _resetTabindices: function() {
+ var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0] : this.selectedItem;
+ this.items.forEach(function(item) {
+ item.setAttribute('tabindex', item === selectedItem ? '0' : '-1');
+ }, this);
+ },
+ _updateMultiselectable: function(multi) {
+ if (multi) {
+ this.setAttribute('aria-multiselectable', 'true');
} else {
- fitTop = this.fitInto.getBoundingClientRect().top;
+ this.removeAttribute('aria-multiselectable');
}
- return fitTop;
},
- get _defaultPositionTarget() {
- var parent = Polymer.dom(this).parentNode;
- if (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
- parent = parent.host;
- }
- return parent;
- },
- get _localeHorizontalAlign() {
- if (this._isRTL) {
- if (this.horizontalAlign === 'right') {
- return 'left';
- }
- if (this.horizontalAlign === 'left') {
- return 'right';
+ _focusWithKeyboardEvent: function(event) {
+ for (var i = 0, item; item = this.items[i]; i++) {
+ var attr = this.attrForItemTitle || 'textContent';
+ var title = item[attr] || item.getAttribute(attr);
+ if (!item.hasAttribute('disabled') && title && title.trim().charAt(0).toLowerCase() === String.fromCharCode(event.keyCode).toLowerCase()) {
+ this._setFocusedItem(item);
+ break;
}
}
- return this.horizontalAlign;
},
- attached: function() {
- this._isRTL = window.getComputedStyle(this).direction == 'rtl';
- this.positionTarget = this.positionTarget || this._defaultPositionTarget;
- if (this.autoFitOnAttach) {
- if (window.getComputedStyle(this).display === 'none') {
- setTimeout(function() {
- this.fit();
- }.bind(this));
- } else {
- this.fit();
+ _focusPrevious: function() {
+ var length = this.items.length;
+ var curFocusIndex = Number(this.indexOf(this.focusedItem));
+ for (var i = 1; i < length + 1; i++) {
+ var item = this.items[(curFocusIndex - i + length) % length];
+ if (!item.hasAttribute('disabled')) {
+ var owner = Polymer.dom(item).getOwnerRoot() || document;
+ this._setFocusedItem(item);
+ if (Polymer.dom(owner).activeElement == item) {
+ return;
+ }
}
}
},
- fit: function() {
- this.position();
- this.constrain();
- this.center();
- },
- _discoverInfo: function() {
- if (this._fitInfo) {
- return;
- }
- var target = window.getComputedStyle(this);
- var sizer = window.getComputedStyle(this.sizingTarget);
- this._fitInfo = {
- inlineStyle: {
- top: this.style.top || '',
- left: this.style.left || '',
- position: this.style.position || ''
- },
- sizerInlineStyle: {
- maxWidth: this.sizingTarget.style.maxWidth || '',
- maxHeight: this.sizingTarget.style.maxHeight || '',
- boxSizing: this.sizingTarget.style.boxSizing || ''
- },
- positionedBy: {
- vertically: target.top !== 'auto' ? 'top' : target.bottom !== 'auto' ? 'bottom' : null,
- horizontally: target.left !== 'auto' ? 'left' : target.right !== 'auto' ? 'right' : null
- },
- sizedBy: {
- height: sizer.maxHeight !== 'none',
- width: sizer.maxWidth !== 'none',
- minWidth: parseInt(sizer.minWidth, 10) || 0,
- minHeight: parseInt(sizer.minHeight, 10) || 0
- },
- margin: {
- top: parseInt(target.marginTop, 10) || 0,
- right: parseInt(target.marginRight, 10) || 0,
- bottom: parseInt(target.marginBottom, 10) || 0,
- left: parseInt(target.marginLeft, 10) || 0
+ _focusNext: function() {
+ var length = this.items.length;
+ var curFocusIndex = Number(this.indexOf(this.focusedItem));
+ for (var i = 1; i < length + 1; i++) {
+ var item = this.items[(curFocusIndex + i) % length];
+ if (!item.hasAttribute('disabled')) {
+ var owner = Polymer.dom(item).getOwnerRoot() || document;
+ this._setFocusedItem(item);
+ if (Polymer.dom(owner).activeElement == item) {
+ return;
+ }
}
- };
- if (this.verticalOffset) {
- this._fitInfo.margin.top = this._fitInfo.margin.bottom = this.verticalOffset;
- this._fitInfo.inlineStyle.marginTop = this.style.marginTop || '';
- this._fitInfo.inlineStyle.marginBottom = this.style.marginBottom || '';
- this.style.marginTop = this.style.marginBottom = this.verticalOffset + 'px';
}
- if (this.horizontalOffset) {
- this._fitInfo.margin.left = this._fitInfo.margin.right = this.horizontalOffset;
- this._fitInfo.inlineStyle.marginLeft = this.style.marginLeft || '';
- this._fitInfo.inlineStyle.marginRight = this.style.marginRight || '';
- this.style.marginLeft = this.style.marginRight = this.horizontalOffset + 'px';
+ },
+ _applySelection: function(item, isSelected) {
+ if (isSelected) {
+ item.setAttribute('aria-selected', 'true');
+ } else {
+ item.removeAttribute('aria-selected');
}
+ Polymer.IronSelectableBehavior._applySelection.apply(this, arguments);
},
- resetFit: function() {
- var info = this._fitInfo || {};
- for (var property in info.sizerInlineStyle) {
- this.sizingTarget.style[property] = info.sizerInlineStyle[property];
+ _focusedItemChanged: function(focusedItem, old) {
+ old && old.setAttribute('tabindex', '-1');
+ if (focusedItem) {
+ focusedItem.setAttribute('tabindex', '0');
+ focusedItem.focus();
}
- for (var property in info.inlineStyle) {
- this.style[property] = info.inlineStyle[property];
+ },
+ _onIronItemsChanged: function(event) {
+ if (event.detail.addedNodes.length) {
+ this._resetTabindices();
}
- this._fitInfo = null;
},
- refit: function() {
- var scrollLeft = this.sizingTarget.scrollLeft;
- var scrollTop = this.sizingTarget.scrollTop;
- this.resetFit();
- this.fit();
- this.sizingTarget.scrollLeft = scrollLeft;
- this.sizingTarget.scrollTop = scrollTop;
+ _onShiftTabDown: function(event) {
+ var oldTabIndex = this.getAttribute('tabindex');
+ Polymer.IronMenuBehaviorImpl._shiftTabPressed = true;
+ this._setFocusedItem(null);
+ this.setAttribute('tabindex', '-1');
+ this.async(function() {
+ this.setAttribute('tabindex', oldTabIndex);
+ Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
+ }, 1);
},
- position: function() {
- if (!this.horizontalAlign && !this.verticalAlign) {
+ _onFocus: function(event) {
+ if (Polymer.IronMenuBehaviorImpl._shiftTabPressed) {
return;
}
- this._discoverInfo();
- this.style.position = 'fixed';
- this.sizingTarget.style.boxSizing = 'border-box';
- this.style.left = '0px';
- this.style.top = '0px';
- var rect = this.getBoundingClientRect();
- var positionRect = this.__getNormalizedRect(this.positionTarget);
- var fitRect = this.__getNormalizedRect(this.fitInto);
- var margin = this._fitInfo.margin;
- var size = {
- width: rect.width + margin.left + margin.right,
- height: rect.height + margin.top + margin.bottom
- };
- var position = this.__getPosition(this._localeHorizontalAlign, this.verticalAlign, size, positionRect, fitRect);
- var left = position.left + margin.left;
- var top = position.top + margin.top;
- var right = Math.min(fitRect.right - margin.right, left + rect.width);
- var bottom = Math.min(fitRect.bottom - margin.bottom, top + rect.height);
- var minWidth = this._fitInfo.sizedBy.minWidth;
- var minHeight = this._fitInfo.sizedBy.minHeight;
- if (left < margin.left) {
- left = margin.left;
- if (right - left < minWidth) {
- left = right - minWidth;
- }
+ var rootTarget = Polymer.dom(event).rootTarget;
+ if (rootTarget !== this && typeof rootTarget.tabIndex !== "undefined" && !this.isLightDescendant(rootTarget)) {
+ return;
}
- if (top < margin.top) {
- top = margin.top;
- if (bottom - top < minHeight) {
- top = bottom - minHeight;
+ this._defaultFocusAsync = this.async(function() {
+ var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0] : this.selectedItem;
+ this._setFocusedItem(null);
+ if (selectedItem) {
+ this._setFocusedItem(selectedItem);
+ } else if (this.items[0]) {
+ this._focusNext();
}
- }
- this.sizingTarget.style.maxWidth = right - left + 'px';
- this.sizingTarget.style.maxHeight = bottom - top + 'px';
- this.style.left = left - rect.left + 'px';
- this.style.top = top - rect.top + 'px';
+ });
},
- constrain: function() {
- if (this.horizontalAlign || this.verticalAlign) {
- return;
- }
- this._discoverInfo();
- var info = this._fitInfo;
- if (!info.positionedBy.vertically) {
- this.style.position = 'fixed';
- this.style.top = '0px';
- }
- if (!info.positionedBy.horizontally) {
- this.style.position = 'fixed';
- this.style.left = '0px';
- }
- this.sizingTarget.style.boxSizing = 'border-box';
- var rect = this.getBoundingClientRect();
- if (!info.sizedBy.height) {
- this.__sizeDimension(rect, info.positionedBy.vertically, 'top', 'bottom', 'Height');
- }
- if (!info.sizedBy.width) {
- this.__sizeDimension(rect, info.positionedBy.horizontally, 'left', 'right', 'Width');
- }
+ _onUpKey: function(event) {
+ this._focusPrevious();
+ event.detail.keyboardEvent.preventDefault();
},
- _sizeDimension: function(rect, positionedBy, start, end, extent) {
- this.__sizeDimension(rect, positionedBy, start, end, extent);
+ _onDownKey: function(event) {
+ this._focusNext();
+ event.detail.keyboardEvent.preventDefault();
},
- __sizeDimension: function(rect, positionedBy, start, end, extent) {
- var info = this._fitInfo;
- var fitRect = this.__getNormalizedRect(this.fitInto);
- var max = extent === 'Width' ? fitRect.width : fitRect.height;
- var flip = positionedBy === end;
- var offset = flip ? max - rect[end] : rect[start];
- var margin = info.margin[flip ? start : end];
- var offsetExtent = 'offset' + extent;
- var sizingOffset = this[offsetExtent] - this.sizingTarget[offsetExtent];
- this.sizingTarget.style['max' + extent] = max - margin - offset - sizingOffset + 'px';
+ _onEscKey: function(event) {
+ this.focusedItem.blur();
},
- center: function() {
- if (this.horizontalAlign || this.verticalAlign) {
- return;
- }
- this._discoverInfo();
- var positionedBy = this._fitInfo.positionedBy;
- if (positionedBy.vertically && positionedBy.horizontally) {
- return;
- }
- this.style.position = 'fixed';
- if (!positionedBy.vertically) {
- this.style.top = '0px';
- }
- if (!positionedBy.horizontally) {
- this.style.left = '0px';
- }
- var rect = this.getBoundingClientRect();
- var fitRect = this.__getNormalizedRect(this.fitInto);
- if (!positionedBy.vertically) {
- var top = fitRect.top - rect.top + (fitRect.height - rect.height) / 2;
- this.style.top = top + 'px';
+ _onKeydown: function(event) {
+ if (!this.keyboardEventMatchesKeys(event, 'up down esc')) {
+ this._focusWithKeyboardEvent(event);
}
- if (!positionedBy.horizontally) {
- var left = fitRect.left - rect.left + (fitRect.width - rect.width) / 2;
- this.style.left = left + 'px';
+ event.stopPropagation();
+ },
+ _activateHandler: function(event) {
+ Polymer.IronSelectableBehavior._activateHandler.call(this, event);
+ event.stopPropagation();
+ }
+};
+
+Polymer.IronMenuBehaviorImpl._shiftTabPressed = false;
+
+Polymer.IronMenuBehavior = [ Polymer.IronMultiSelectableBehavior, Polymer.IronA11yKeysBehavior, Polymer.IronMenuBehaviorImpl ];
+
+Polymer.IronMenubarBehaviorImpl = {
+ hostAttributes: {
+ role: 'menubar'
+ },
+ keyBindings: {
+ left: '_onLeftKey',
+ right: '_onRightKey'
+ },
+ _onUpKey: function(event) {
+ this.focusedItem.click();
+ event.detail.keyboardEvent.preventDefault();
+ },
+ _onDownKey: function(event) {
+ this.focusedItem.click();
+ event.detail.keyboardEvent.preventDefault();
+ },
+ get _isRTL() {
+ return window.getComputedStyle(this)['direction'] === 'rtl';
+ },
+ _onLeftKey: function(event) {
+ if (this._isRTL) {
+ this._focusNext();
+ } else {
+ this._focusPrevious();
}
+ event.detail.keyboardEvent.preventDefault();
},
- __getNormalizedRect: function(target) {
- if (target === document.documentElement || target === window) {
- return {
- top: 0,
- left: 0,
- width: window.innerWidth,
- height: window.innerHeight,
- right: window.innerWidth,
- bottom: window.innerHeight
- };
+ _onRightKey: function(event) {
+ if (this._isRTL) {
+ this._focusPrevious();
+ } else {
+ this._focusNext();
}
- return target.getBoundingClientRect();
+ event.detail.keyboardEvent.preventDefault();
},
- __getCroppedArea: function(position, size, fitRect) {
- var verticalCrop = Math.min(0, position.top) + Math.min(0, fitRect.bottom - (position.top + size.height));
- var horizontalCrop = Math.min(0, position.left) + Math.min(0, fitRect.right - (position.left + size.width));
- return Math.abs(verticalCrop) * size.width + Math.abs(horizontalCrop) * size.height;
+ _onKeydown: function(event) {
+ if (this.keyboardEventMatchesKeys(event, 'up down left right esc')) {
+ return;
+ }
+ this._focusWithKeyboardEvent(event);
+ }
+};
+
+Polymer.IronMenubarBehavior = [ Polymer.IronMenuBehavior, Polymer.IronMenubarBehaviorImpl ];
+
+Polymer({
+ is: 'iron-iconset-svg',
+ properties: {
+ name: {
+ type: String,
+ observer: '_nameChanged'
+ },
+ size: {
+ type: Number,
+ value: 24
+ }
},
- __getPosition: function(hAlign, vAlign, size, positionRect, fitRect) {
- var positions = [ {
- verticalAlign: 'top',
- horizontalAlign: 'left',
- top: positionRect.top,
- left: positionRect.left
- }, {
- verticalAlign: 'top',
- horizontalAlign: 'right',
- top: positionRect.top,
- left: positionRect.right - size.width
- }, {
- verticalAlign: 'bottom',
- horizontalAlign: 'left',
- top: positionRect.bottom - size.height,
- left: positionRect.left
- }, {
- verticalAlign: 'bottom',
- horizontalAlign: 'right',
- top: positionRect.bottom - size.height,
- left: positionRect.right - size.width
- } ];
- if (this.noOverlap) {
- for (var i = 0, l = positions.length; i < l; i++) {
- var copy = {};
- for (var key in positions[i]) {
- copy[key] = positions[i][key];
- }
- positions.push(copy);
- }
- positions[0].top = positions[1].top += positionRect.height;
- positions[2].top = positions[3].top -= positionRect.height;
- positions[4].left = positions[6].left += positionRect.width;
- positions[5].left = positions[7].left -= positionRect.width;
+ attached: function() {
+ this.style.display = 'none';
+ },
+ getIconNames: function() {
+ this._icons = this._createIconMap();
+ return Object.keys(this._icons).map(function(n) {
+ return this.name + ':' + n;
+ }, this);
+ },
+ applyIcon: function(element, iconName) {
+ element = element.root || element;
+ this.removeIcon(element);
+ var svg = this._cloneIcon(iconName);
+ if (svg) {
+ var pde = Polymer.dom(element);
+ pde.insertBefore(svg, pde.childNodes[0]);
+ return element._svgIcon = svg;
}
- vAlign = vAlign === 'auto' ? null : vAlign;
- hAlign = hAlign === 'auto' ? null : hAlign;
- var position;
- for (var i = 0; i < positions.length; i++) {
- var pos = positions[i];
- if (!this.dynamicAlign && !this.noOverlap && pos.verticalAlign === vAlign && pos.horizontalAlign === hAlign) {
- position = pos;
- break;
- }
- var alignOk = (!vAlign || pos.verticalAlign === vAlign) && (!hAlign || pos.horizontalAlign === hAlign);
- if (!this.dynamicAlign && !alignOk) {
- continue;
- }
- position = position || pos;
- pos.croppedArea = this.__getCroppedArea(pos, size, fitRect);
- var diff = pos.croppedArea - position.croppedArea;
- if (diff < 0 || diff === 0 && alignOk) {
- position = pos;
- }
- if (position.croppedArea === 0 && alignOk) {
- break;
- }
+ return null;
+ },
+ removeIcon: function(element) {
+ if (element._svgIcon) {
+ Polymer.dom(element).removeChild(element._svgIcon);
+ element._svgIcon = null;
}
- return position;
+ },
+ _nameChanged: function() {
+ new Polymer.IronMeta({
+ type: 'iconset',
+ key: this.name,
+ value: this
+ });
+ this.async(function() {
+ this.fire('iron-iconset-added', this, {
+ node: window
+ });
+ });
+ },
+ _createIconMap: function() {
+ var icons = Object.create(null);
+ Polymer.dom(this).querySelectorAll('[id]').forEach(function(icon) {
+ icons[icon.id] = icon;
+ });
+ return icons;
+ },
+ _cloneIcon: function(id) {
+ this._icons = this._icons || this._createIconMap();
+ return this._prepareSvgClone(this._icons[id], this.size);
+ },
+ _prepareSvgClone: function(sourceSvg, size) {
+ if (sourceSvg) {
+ var content = sourceSvg.cloneNode(true), svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'), viewBox = content.getAttribute('viewBox') || '0 0 ' + size + ' ' + size;
+ svg.setAttribute('viewBox', viewBox);
+ svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
+ svg.style.cssText = 'pointer-events: none; display: block; width: 100%; height: 100%;';
+ svg.appendChild(content).removeAttribute('id');
+ return svg;
+ }
+ return null;
}
-};
+});
-(function() {
- 'use strict';
- Polymer({
- is: 'iron-overlay-backdrop',
- properties: {
- opened: {
- reflectToAttribute: true,
- type: Boolean,
- value: false,
- observer: '_openedChanged'
- }
+Polymer({
+ is: 'paper-tabs',
+ behaviors: [ Polymer.IronResizableBehavior, Polymer.IronMenubarBehavior ],
+ properties: {
+ noink: {
+ type: Boolean,
+ value: false,
+ observer: '_noinkChanged'
},
- listeners: {
- transitionend: '_onTransitionend'
+ noBar: {
+ type: Boolean,
+ value: false
},
- created: function() {
- this.__openedRaf = null;
+ noSlide: {
+ type: Boolean,
+ value: false
},
- attached: function() {
- this.opened && this._openedChanged(this.opened);
+ scrollable: {
+ type: Boolean,
+ value: false
},
- prepare: function() {
- if (this.opened && !this.parentNode) {
- Polymer.dom(document.body).appendChild(this);
- }
+ fitContainer: {
+ type: Boolean,
+ value: false
},
- open: function() {
- this.opened = true;
+ disableDrag: {
+ type: Boolean,
+ value: false
},
- close: function() {
- this.opened = false;
+ hideScrollButtons: {
+ type: Boolean,
+ value: false
},
- complete: function() {
- if (!this.opened && this.parentNode === document.body) {
- Polymer.dom(this.parentNode).removeChild(this);
- }
+ alignBottom: {
+ type: Boolean,
+ value: false
},
- _onTransitionend: function(event) {
- if (event && event.target === this) {
- this.complete();
- }
+ selectable: {
+ type: String,
+ value: 'paper-tab'
},
- _openedChanged: function(opened) {
- if (opened) {
- this.prepare();
- } else {
- var cs = window.getComputedStyle(this);
- if (cs.transitionDuration === '0s' || cs.opacity == 0) {
- this.complete();
- }
- }
- if (!this.isAttached) {
- return;
- }
- if (this.__openedRaf) {
- window.cancelAnimationFrame(this.__openedRaf);
- this.__openedRaf = null;
- }
- this.scrollTop = this.scrollTop;
- this.__openedRaf = window.requestAnimationFrame(function() {
- this.__openedRaf = null;
- this.toggleClass('opened', this.opened);
- }.bind(this));
- }
- });
-})();
-
-Polymer.IronOverlayManagerClass = function() {
- this._overlays = [];
- this._minimumZ = 101;
- this._backdropElement = null;
- Polymer.Gestures.add(document, 'tap', this._onCaptureClick.bind(this));
- document.addEventListener('focus', this._onCaptureFocus.bind(this), true);
- document.addEventListener('keydown', this._onCaptureKeyDown.bind(this), true);
-};
-
-Polymer.IronOverlayManagerClass.prototype = {
- constructor: Polymer.IronOverlayManagerClass,
- get backdropElement() {
- if (!this._backdropElement) {
- this._backdropElement = document.createElement('iron-overlay-backdrop');
+ autoselect: {
+ type: Boolean,
+ value: false
+ },
+ autoselectDelay: {
+ type: Number,
+ value: 0
+ },
+ _step: {
+ type: Number,
+ value: 10
+ },
+ _holdDelay: {
+ type: Number,
+ value: 1
+ },
+ _leftHidden: {
+ type: Boolean,
+ value: false
+ },
+ _rightHidden: {
+ type: Boolean,
+ value: false
+ },
+ _previousTab: {
+ type: Object
}
- return this._backdropElement;
},
- get deepActiveElement() {
- var active = document.activeElement || document.body;
- while (active.root && Polymer.dom(active.root).activeElement) {
- active = Polymer.dom(active.root).activeElement;
- }
- return active;
+ hostAttributes: {
+ role: 'tablist'
},
- _bringOverlayAtIndexToFront: function(i) {
- var overlay = this._overlays[i];
- if (!overlay) {
- return;
- }
- var lastI = this._overlays.length - 1;
- var currentOverlay = this._overlays[lastI];
- if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay)) {
- lastI--;
- }
- if (i >= lastI) {
- return;
- }
- var minimumZ = Math.max(this.currentOverlayZ(), this._minimumZ);
- if (this._getZ(overlay) <= minimumZ) {
- this._applyOverlayZ(overlay, minimumZ);
- }
- while (i < lastI) {
- this._overlays[i] = this._overlays[i + 1];
- i++;
- }
- this._overlays[lastI] = overlay;
+ listeners: {
+ 'iron-resize': '_onTabSizingChanged',
+ 'iron-items-changed': '_onTabSizingChanged',
+ 'iron-select': '_onIronSelect',
+ 'iron-deselect': '_onIronDeselect'
},
- addOrRemoveOverlay: function(overlay) {
- if (overlay.opened) {
- this.addOverlay(overlay);
- } else {
- this.removeOverlay(overlay);
- }
+ keyBindings: {
+ 'left:keyup right:keyup': '_onArrowKeyup'
},
- addOverlay: function(overlay) {
- var i = this._overlays.indexOf(overlay);
- if (i >= 0) {
- this._bringOverlayAtIndexToFront(i);
- this.trackBackdrop();
- return;
- }
- var insertionIndex = this._overlays.length;
- var currentOverlay = this._overlays[insertionIndex - 1];
- var minimumZ = Math.max(this._getZ(currentOverlay), this._minimumZ);
- var newZ = this._getZ(overlay);
- if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay)) {
- this._applyOverlayZ(currentOverlay, minimumZ);
- insertionIndex--;
- var previousOverlay = this._overlays[insertionIndex - 1];
- minimumZ = Math.max(this._getZ(previousOverlay), this._minimumZ);
- }
- if (newZ <= minimumZ) {
- this._applyOverlayZ(overlay, minimumZ);
- }
- this._overlays.splice(insertionIndex, 0, overlay);
- this.trackBackdrop();
+ created: function() {
+ this._holdJob = null;
+ this._pendingActivationItem = undefined;
+ this._pendingActivationTimeout = undefined;
+ this._bindDelayedActivationHandler = this._delayedActivationHandler.bind(this);
+ this.addEventListener('blur', this._onBlurCapture.bind(this), true);
},
- removeOverlay: function(overlay) {
- var i = this._overlays.indexOf(overlay);
- if (i === -1) {
- return;
- }
- this._overlays.splice(i, 1);
- this.trackBackdrop();
+ ready: function() {
+ this.setScrollDirection('y', this.$.tabsContainer);
},
- currentOverlay: function() {
- var i = this._overlays.length - 1;
- return this._overlays[i];
+ detached: function() {
+ this._cancelPendingActivation();
},
- currentOverlayZ: function() {
- return this._getZ(this.currentOverlay());
+ _noinkChanged: function(noink) {
+ var childTabs = Polymer.dom(this).querySelectorAll('paper-tab');
+ childTabs.forEach(noink ? this._setNoinkAttribute : this._removeNoinkAttribute);
},
- ensureMinimumZ: function(minimumZ) {
- this._minimumZ = Math.max(this._minimumZ, minimumZ);
+ _setNoinkAttribute: function(element) {
+ element.setAttribute('noink', '');
},
- focusOverlay: function() {
- var current = this.currentOverlay();
- if (current) {
- current._applyFocus();
- }
+ _removeNoinkAttribute: function(element) {
+ element.removeAttribute('noink');
},
- trackBackdrop: function() {
- var overlay = this._overlayWithBackdrop();
- if (!overlay && !this._backdropElement) {
- return;
+ _computeScrollButtonClass: function(hideThisButton, scrollable, hideScrollButtons) {
+ if (!scrollable || hideScrollButtons) {
+ return 'hidden';
}
- this.backdropElement.style.zIndex = this._getZ(overlay) - 1;
- this.backdropElement.opened = !!overlay;
- },
- getBackdrops: function() {
- var backdrops = [];
- for (var i = 0; i < this._overlays.length; i++) {
- if (this._overlays[i].withBackdrop) {
- backdrops.push(this._overlays[i]);
- }
+ if (hideThisButton) {
+ return 'not-visible';
}
- return backdrops;
+ return '';
},
- backdropZ: function() {
- return this._getZ(this._overlayWithBackdrop()) - 1;
+ _computeTabsContentClass: function(scrollable, fitContainer) {
+ return scrollable ? 'scrollable' + (fitContainer ? ' fit-container' : '') : ' fit-container';
},
- _overlayWithBackdrop: function() {
- for (var i = 0; i < this._overlays.length; i++) {
- if (this._overlays[i].withBackdrop) {
- return this._overlays[i];
- }
+ _computeSelectionBarClass: function(noBar, alignBottom) {
+ if (noBar) {
+ return 'hidden';
+ } else if (alignBottom) {
+ return 'align-bottom';
}
+ return '';
},
- _getZ: function(overlay) {
- var z = this._minimumZ;
- if (overlay) {
- var z1 = Number(overlay.style.zIndex || window.getComputedStyle(overlay).zIndex);
- if (z1 === z1) {
- z = z1;
- }
- }
- return z;
+ _onTabSizingChanged: function() {
+ this.debounce('_onTabSizingChanged', function() {
+ this._scroll();
+ this._tabChanged(this.selectedItem);
+ }, 10);
},
- _setZ: function(element, z) {
- element.style.zIndex = z;
+ _onIronSelect: function(event) {
+ this._tabChanged(event.detail.item, this._previousTab);
+ this._previousTab = event.detail.item;
+ this.cancelDebouncer('tab-changed');
},
- _applyOverlayZ: function(overlay, aboveZ) {
- this._setZ(overlay, aboveZ + 2);
+ _onIronDeselect: function(event) {
+ this.debounce('tab-changed', function() {
+ this._tabChanged(null, this._previousTab);
+ this._previousTab = null;
+ }, 1);
},
- _overlayInPath: function(path) {
- path = path || [];
- for (var i = 0; i < path.length; i++) {
- if (path[i]._manager === this) {
- return path[i];
- }
- }
+ _activateHandler: function() {
+ this._cancelPendingActivation();
+ Polymer.IronMenuBehaviorImpl._activateHandler.apply(this, arguments);
},
- _onCaptureClick: function(event) {
- var overlay = this.currentOverlay();
- if (overlay && this._overlayInPath(Polymer.dom(event).path) !== overlay) {
- overlay._onCaptureClick(event);
- }
+ _scheduleActivation: function(item, delay) {
+ this._pendingActivationItem = item;
+ this._pendingActivationTimeout = this.async(this._bindDelayedActivationHandler, delay);
},
- _onCaptureFocus: function(event) {
- var overlay = this.currentOverlay();
- if (overlay) {
- overlay._onCaptureFocus(event);
+ _delayedActivationHandler: function() {
+ var item = this._pendingActivationItem;
+ this._pendingActivationItem = undefined;
+ this._pendingActivationTimeout = undefined;
+ item.fire(this.activateEvent, null, {
+ bubbles: true,
+ cancelable: true
+ });
+ },
+ _cancelPendingActivation: function() {
+ if (this._pendingActivationTimeout !== undefined) {
+ this.cancelAsync(this._pendingActivationTimeout);
+ this._pendingActivationItem = undefined;
+ this._pendingActivationTimeout = undefined;
}
},
- _onCaptureKeyDown: function(event) {
- var overlay = this.currentOverlay();
- if (overlay) {
- if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(event, 'esc')) {
- overlay._onCaptureEsc(event);
- } else if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(event, 'tab')) {
- overlay._onCaptureTab(event);
+ _onArrowKeyup: function(event) {
+ if (this.autoselect) {
+ this._scheduleActivation(this.focusedItem, this.autoselectDelay);
+ }
+ },
+ _onBlurCapture: function(event) {
+ if (event.target === this._pendingActivationItem) {
+ this._cancelPendingActivation();
+ }
+ },
+ get _tabContainerScrollSize() {
+ return Math.max(0, this.$.tabsContainer.scrollWidth - this.$.tabsContainer.offsetWidth);
+ },
+ _scroll: function(e, detail) {
+ if (!this.scrollable) {
+ return;
+ }
+ var ddx = detail && -detail.ddx || 0;
+ this._affectScroll(ddx);
+ },
+ _down: function(e) {
+ 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.$.selectionBar.classList.remove('expand');
+ this.$.selectionBar.classList.remove('contract');
+ 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) {
+ this.$.selectionBar.classList.remove('expand');
+ this.$.selectionBar.classList.remove('contract');
+ 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;
+ this.$.selectionBar.classList.add('expand');
+ var moveRight = oldIndex < index;
+ var isRTL = this._isRTL;
+ if (isRTL) {
+ moveRight = !moveRight;
+ }
+ if (moveRight) {
+ 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);
}
},
- _shouldBeBehindOverlay: function(overlay1, overlay2) {
- return !overlay1.alwaysOnTop && overlay2.alwaysOnTop;
+ _scrollToSelectedIfNeeded: function(tabWidth, tabOffsetLeft) {
+ var l = tabOffsetLeft - this.$.tabsContainer.scrollLeft;
+ if (l < 0) {
+ this.$.tabsContainer.scrollLeft += l;
+ } else {
+ l += tabWidth - this.$.tabsContainer.offsetWidth;
+ if (l > 0) {
+ this.$.tabsContainer.scrollLeft += l;
+ }
+ }
+ },
+ _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('translateX(' + left + '%) scaleX(' + width / 100 + ')', this.$.selectionBar);
+ },
+ _onBarTransitionEnd: function(e) {
+ var cl = this.$.selectionBar.classList;
+ if (cl.contains('expand')) {
+ cl.remove('expand');
+ cl.add('contract');
+ this._positionBar(this._pos.width, this._pos.left);
+ } else if (cl.contains('contract')) {
+ cl.remove('contract');
+ }
}
-};
-
-Polymer.IronOverlayManager = new Polymer.IronOverlayManagerClass();
+});
(function() {
'use strict';
- Polymer.IronOverlayBehaviorImpl = {
+ Polymer.IronA11yAnnouncer = Polymer({
+ is: 'iron-a11y-announcer',
properties: {
- opened: {
- observer: '_openedChanged',
- type: Boolean,
- value: false,
- notify: true
- },
- canceled: {
- observer: '_canceledChanged',
- readOnly: true,
- type: Boolean,
- value: false
- },
- withBackdrop: {
- observer: '_withBackdropChanged',
- type: Boolean
- },
- noAutoFocus: {
- type: Boolean,
- value: false
- },
- noCancelOnEscKey: {
- type: Boolean,
- value: false
- },
- noCancelOnOutsideClick: {
- type: Boolean,
- value: false
- },
- closingReason: {
- type: Object
- },
- restoreFocusOnClose: {
- type: Boolean,
- value: false
- },
- alwaysOnTop: {
- type: Boolean
- },
- _manager: {
- type: Object,
- value: Polymer.IronOverlayManager
+ mode: {
+ type: String,
+ value: 'polite'
},
- _focusedChild: {
- type: Object
- }
- },
- listeners: {
- 'iron-resize': '_onIronResize'
- },
- get backdropElement() {
- return this._manager.backdropElement;
- },
- get _focusNode() {
- return this._focusedChild || Polymer.dom(this).querySelector('[autofocus]') || this;
- },
- get _focusableNodes() {
- var FOCUSABLE_WITH_DISABLED = [ 'a[href]', 'area[href]', 'iframe', '[tabindex]', '[contentEditable=true]' ];
- var FOCUSABLE_WITHOUT_DISABLED = [ 'input', 'select', 'textarea', 'button' ];
- var selector = FOCUSABLE_WITH_DISABLED.join(':not([tabindex="-1"]),') + ':not([tabindex="-1"]),' + FOCUSABLE_WITHOUT_DISABLED.join(':not([disabled]):not([tabindex="-1"]),') + ':not([disabled]):not([tabindex="-1"])';
- var focusables = Polymer.dom(this).querySelectorAll(selector);
- if (this.tabIndex >= 0) {
- focusables.splice(0, 0, this);
- }
- return focusables.sort(function(a, b) {
- if (a.tabIndex === b.tabIndex) {
- return 0;
- }
- if (a.tabIndex === 0 || a.tabIndex > b.tabIndex) {
- return 1;
- }
- return -1;
- });
- },
- ready: function() {
- this.__isAnimating = false;
- this.__shouldRemoveTabIndex = false;
- this.__firstFocusableNode = this.__lastFocusableNode = null;
- this.__raf = null;
- this.__restoreFocusNode = null;
- this._ensureSetup();
- },
- attached: function() {
- if (this.opened) {
- this._openedChanged(this.opened);
- }
- this._observer = Polymer.dom(this).observeNodes(this._onNodesChange);
- },
- detached: function() {
- Polymer.dom(this).unobserveNodes(this._observer);
- this._observer = null;
- if (this.__raf) {
- window.cancelAnimationFrame(this.__raf);
- this.__raf = null;
- }
- this._manager.removeOverlay(this);
- },
- toggle: function() {
- this._setCanceled(false);
- this.opened = !this.opened;
- },
- open: function() {
- this._setCanceled(false);
- this.opened = true;
- },
- close: function() {
- this._setCanceled(false);
- this.opened = false;
- },
- cancel: function(event) {
- var cancelEvent = this.fire('iron-overlay-canceled', event, {
- cancelable: true
- });
- if (cancelEvent.defaultPrevented) {
- return;
- }
- this._setCanceled(true);
- this.opened = false;
- },
- _ensureSetup: function() {
- if (this._overlaySetup) {
- return;
- }
- this._overlaySetup = true;
- this.style.outline = 'none';
- this.style.display = 'none';
- },
- _openedChanged: function(opened) {
- if (opened) {
- this.removeAttribute('aria-hidden');
- } else {
- this.setAttribute('aria-hidden', 'true');
- }
- if (!this.isAttached) {
- return;
- }
- this.__isAnimating = true;
- this.__onNextAnimationFrame(this.__openedChanged);
- },
- _canceledChanged: function() {
- this.closingReason = this.closingReason || {};
- this.closingReason.canceled = this.canceled;
- },
- _withBackdropChanged: function() {
- if (this.withBackdrop && !this.hasAttribute('tabindex')) {
- this.setAttribute('tabindex', '-1');
- this.__shouldRemoveTabIndex = true;
- } else if (this.__shouldRemoveTabIndex) {
- this.removeAttribute('tabindex');
- this.__shouldRemoveTabIndex = false;
- }
- if (this.opened && this.isAttached) {
- this._manager.trackBackdrop();
- }
- },
- _prepareRenderOpened: function() {
- this.__restoreFocusNode = this._manager.deepActiveElement;
- this._preparePositioning();
- this.refit();
- this._finishPositioning();
- if (this.noAutoFocus && document.activeElement === this._focusNode) {
- this._focusNode.blur();
- this.__restoreFocusNode.focus();
- }
- },
- _renderOpened: function() {
- this._finishRenderOpened();
- },
- _renderClosed: function() {
- this._finishRenderClosed();
- },
- _finishRenderOpened: function() {
- this.notifyResize();
- this.__isAnimating = false;
- var focusableNodes = this._focusableNodes;
- this.__firstFocusableNode = focusableNodes[0];
- this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1];
- this.fire('iron-overlay-opened');
- },
- _finishRenderClosed: function() {
- this.style.display = 'none';
- this.style.zIndex = '';
- this.notifyResize();
- this.__isAnimating = false;
- this.fire('iron-overlay-closed', this.closingReason);
- },
- _preparePositioning: function() {
- this.style.transition = this.style.webkitTransition = 'none';
- this.style.transform = this.style.webkitTransform = 'none';
- this.style.display = '';
- },
- _finishPositioning: function() {
- this.style.display = 'none';
- this.scrollTop = this.scrollTop;
- this.style.transition = this.style.webkitTransition = '';
- this.style.transform = this.style.webkitTransform = '';
- this.style.display = '';
- this.scrollTop = this.scrollTop;
- },
- _applyFocus: function() {
- if (this.opened) {
- if (!this.noAutoFocus) {
- this._focusNode.focus();
- }
- } else {
- this._focusNode.blur();
- this._focusedChild = null;
- if (this.restoreFocusOnClose && this.__restoreFocusNode) {
- this.__restoreFocusNode.focus();
- }
- this.__restoreFocusNode = null;
- var currentOverlay = this._manager.currentOverlay();
- if (currentOverlay && this !== currentOverlay) {
- currentOverlay._applyFocus();
- }
- }
- },
- _onCaptureClick: function(event) {
- if (!this.noCancelOnOutsideClick) {
- this.cancel(event);
- }
- },
- _onCaptureFocus: function(event) {
- if (!this.withBackdrop) {
- return;
- }
- var path = Polymer.dom(event).path;
- if (path.indexOf(this) === -1) {
- event.stopPropagation();
- this._applyFocus();
- } else {
- this._focusedChild = path[0];
- }
- },
- _onCaptureEsc: function(event) {
- if (!this.noCancelOnEscKey) {
- this.cancel(event);
- }
- },
- _onCaptureTab: function(event) {
- if (!this.withBackdrop) {
- return;
- }
- var shift = event.shiftKey;
- var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusableNode;
- var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNode;
- var shouldWrap = false;
- if (nodeToCheck === nodeToSet) {
- shouldWrap = true;
- } else {
- var focusedNode = this._manager.deepActiveElement;
- shouldWrap = focusedNode === nodeToCheck || focusedNode === this;
- }
- if (shouldWrap) {
- event.preventDefault();
- this._focusedChild = nodeToSet;
- this._applyFocus();
- }
- },
- _onIronResize: function() {
- if (this.opened && !this.__isAnimating) {
- this.__onNextAnimationFrame(this.refit);
- }
- },
- _onNodesChange: function() {
- if (this.opened && !this.__isAnimating) {
- this.notifyResize();
+ _text: {
+ type: String,
+ value: ''
}
},
- __openedChanged: function() {
- if (this.opened) {
- this._prepareRenderOpened();
- this._manager.addOverlay(this);
- this._applyFocus();
- this._renderOpened();
- } else {
- this._manager.removeOverlay(this);
- this._applyFocus();
- this._renderClosed();
+ created: function() {
+ if (!Polymer.IronA11yAnnouncer.instance) {
+ Polymer.IronA11yAnnouncer.instance = this;
}
+ document.body.addEventListener('iron-announce', this._onIronAnnounce.bind(this));
},
- __onNextAnimationFrame: function(callback) {
- if (this.__raf) {
- window.cancelAnimationFrame(this.__raf);
+ announce: function(text) {
+ this._text = '';
+ this.async(function() {
+ this._text = text;
+ }, 100);
+ },
+ _onIronAnnounce: function(event) {
+ if (event.detail && event.detail.text) {
+ this.announce(event.detail.text);
}
- var self = this;
- this.__raf = window.requestAnimationFrame(function nextAnimationFrame() {
- self.__raf = null;
- callback.call(self);
- });
}
+ });
+ Polymer.IronA11yAnnouncer.instance = null;
+ Polymer.IronA11yAnnouncer.requestAvailability = function() {
+ if (!Polymer.IronA11yAnnouncer.instance) {
+ Polymer.IronA11yAnnouncer.instance = document.createElement('iron-a11y-announcer');
+ }
+ document.body.appendChild(Polymer.IronA11yAnnouncer.instance);
};
- Polymer.IronOverlayBehavior = [ Polymer.IronFitBehavior, Polymer.IronResizableBehavior, Polymer.IronOverlayBehaviorImpl ];
})();
-Polymer.NeonAnimatableBehavior = {
+Polymer.IronValidatableBehaviorMeta = null;
+
+Polymer.IronValidatableBehavior = {
properties: {
- animationConfig: {
+ validator: {
+ type: String
+ },
+ invalid: {
+ notify: true,
+ reflectToAttribute: true,
+ type: Boolean,
+ value: false
+ },
+ _validatorMeta: {
type: Object
},
- entryAnimation: {
- observer: '_entryAnimationChanged',
- type: String
+ validatorType: {
+ type: String,
+ value: 'validator'
},
- exitAnimation: {
- observer: '_exitAnimationChanged',
- type: String
+ _validator: {
+ type: Object,
+ computed: '__computeValidator(validator)'
}
},
- _entryAnimationChanged: function() {
- this.animationConfig = this.animationConfig || {};
- this.animationConfig['entry'] = [ {
- name: this.entryAnimation,
- node: this
- } ];
- },
- _exitAnimationChanged: function() {
- this.animationConfig = this.animationConfig || {};
- this.animationConfig['exit'] = [ {
- name: this.exitAnimation,
- node: this
- } ];
+ observers: [ '_invalidChanged(invalid)' ],
+ registered: function() {
+ Polymer.IronValidatableBehaviorMeta = new Polymer.IronMeta({
+ type: 'validator'
+ });
},
- _copyProperties: function(config1, config2) {
- for (var property in config2) {
- config1[property] = config2[property];
+ _invalidChanged: function() {
+ if (this.invalid) {
+ this.setAttribute('aria-invalid', 'true');
+ } else {
+ this.removeAttribute('aria-invalid');
}
},
- _cloneConfig: function(config) {
- var clone = {
- isClone: true
- };
- this._copyProperties(clone, config);
- return clone;
+ hasValidator: function() {
+ return this._validator != null;
},
- _getAnimationConfigRecursive: function(type, map, allConfigs) {
- if (!this.animationConfig) {
- return;
- }
- if (this.animationConfig.value && typeof this.animationConfig.value === 'function') {
- this._warn(this._logf('playAnimation', "Please put 'animationConfig' inside of your components 'properties' object instead of outside of it."));
- return;
- }
- var thisConfig;
- if (type) {
- thisConfig = this.animationConfig[type];
- } else {
- thisConfig = this.animationConfig;
- }
- if (!Array.isArray(thisConfig)) {
- thisConfig = [ thisConfig ];
- }
- if (thisConfig) {
- for (var config, index = 0; config = thisConfig[index]; index++) {
- if (config.animatable) {
- config.animatable._getAnimationConfigRecursive(config.type || type, map, allConfigs);
- } else {
- if (config.id) {
- var cachedConfig = map[config.id];
- if (cachedConfig) {
- if (!cachedConfig.isClone) {
- map[config.id] = this._cloneConfig(cachedConfig);
- cachedConfig = map[config.id];
- }
- this._copyProperties(cachedConfig, config);
- } else {
- map[config.id] = config;
- }
- } else {
- allConfigs.push(config);
- }
- }
- }
- }
+ validate: function(value) {
+ this.invalid = !this._getValidity(value);
+ return !this.invalid;
},
- getAnimationConfig: function(type) {
- var map = {};
- var allConfigs = [];
- this._getAnimationConfigRecursive(type, map, allConfigs);
- for (var key in map) {
- allConfigs.push(map[key]);
+ _getValidity: function(value) {
+ if (this.hasValidator()) {
+ return this._validator.validate(value);
}
- return allConfigs;
+ return true;
+ },
+ __computeValidator: function() {
+ return Polymer.IronValidatableBehaviorMeta && Polymer.IronValidatableBehaviorMeta.byKey(this.validator);
}
};
-Polymer.NeonAnimationRunnerBehaviorImpl = {
- _configureAnimations: function(configs) {
- var results = [];
- if (configs.length > 0) {
- for (var config, index = 0; config = configs[index]; index++) {
- var neonAnimation = document.createElement(config.name);
- if (neonAnimation.isNeonAnimation) {
- var result = null;
- try {
- result = neonAnimation.configure(config);
- if (typeof result.cancel != 'function') {
- result = document.timeline.play(result);
- }
- } catch (e) {
- result = null;
- console.warn('Couldnt play', '(', config.name, ').', e);
- }
- if (result) {
- results.push({
- neonAnimation: neonAnimation,
- config: config,
- animation: result
- });
- }
- } else {
- console.warn(this.is + ':', config.name, 'not found!');
- }
- }
+Polymer({
+ is: 'iron-input',
+ "extends": 'input',
+ behaviors: [ Polymer.IronValidatableBehavior ],
+ properties: {
+ bindValue: {
+ observer: '_bindValueChanged',
+ type: String
+ },
+ preventInvalidInput: {
+ type: Boolean
+ },
+ allowedPattern: {
+ type: String,
+ observer: "_allowedPatternChanged"
+ },
+ _previousValidInput: {
+ type: String,
+ value: ''
+ },
+ _patternAlreadyChecked: {
+ type: Boolean,
+ value: false
}
- return results;
},
- _shouldComplete: function(activeEntries) {
- var finished = true;
- for (var i = 0; i < activeEntries.length; i++) {
- if (activeEntries[i].animation.playState != 'finished') {
- finished = false;
+ listeners: {
+ input: '_onInput',
+ keypress: '_onKeypress'
+ },
+ registered: function() {
+ if (!this._canDispatchEventOnDisabled()) {
+ this._origDispatchEvent = this.dispatchEvent;
+ this.dispatchEvent = this._dispatchEventFirefoxIE;
+ }
+ },
+ created: function() {
+ Polymer.IronA11yAnnouncer.requestAvailability();
+ },
+ _canDispatchEventOnDisabled: function() {
+ var input = document.createElement('input');
+ var canDispatch = false;
+ input.disabled = true;
+ input.addEventListener('feature-check-dispatch-event', function() {
+ canDispatch = true;
+ });
+ try {
+ input.dispatchEvent(new Event('feature-check-dispatch-event'));
+ } catch (e) {}
+ return canDispatch;
+ },
+ _dispatchEventFirefoxIE: function() {
+ var disabled = this.disabled;
+ this.disabled = false;
+ this._origDispatchEvent.apply(this, arguments);
+ this.disabled = disabled;
+ },
+ get _patternRegExp() {
+ var pattern;
+ if (this.allowedPattern) {
+ pattern = new RegExp(this.allowedPattern);
+ } else {
+ switch (this.type) {
+ case 'number':
+ pattern = /[0-9.,e-]/;
break;
}
}
- return finished;
+ return pattern;
},
- _complete: function(activeEntries) {
- for (var i = 0; i < activeEntries.length; i++) {
- activeEntries[i].neonAnimation.complete(activeEntries[i].config);
+ ready: function() {
+ this.bindValue = this.value;
+ },
+ _bindValueChanged: function() {
+ if (this.value !== this.bindValue) {
+ this.value = !(this.bindValue || this.bindValue === 0 || this.bindValue === false) ? '' : this.bindValue;
}
- for (var i = 0; i < activeEntries.length; i++) {
- activeEntries[i].animation.cancel();
+ this.fire('bind-value-changed', {
+ value: this.bindValue
+ });
+ },
+ _allowedPatternChanged: function() {
+ this.preventInvalidInput = this.allowedPattern ? true : false;
+ },
+ _onInput: function() {
+ if (this.preventInvalidInput && !this._patternAlreadyChecked) {
+ var valid = this._checkPatternValidity();
+ if (!valid) {
+ this._announceInvalidCharacter('Invalid string of characters not entered.');
+ this.value = this._previousValidInput;
+ }
}
+ this.bindValue = this.value;
+ this._previousValidInput = this.value;
+ this._patternAlreadyChecked = false;
},
- playAnimation: function(type, cookie) {
- var configs = this.getAnimationConfig(type);
- if (!configs) {
+ _isPrintable: function(event) {
+ var anyNonPrintable = event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 13 || event.keyCode == 27;
+ var mozNonPrintable = event.keyCode == 19 || event.keyCode == 20 || event.keyCode == 45 || event.keyCode == 46 || event.keyCode == 144 || event.keyCode == 145 || event.keyCode > 32 && event.keyCode < 41 || event.keyCode > 111 && event.keyCode < 124;
+ return !anyNonPrintable && !(event.charCode == 0 && mozNonPrintable);
+ },
+ _onKeypress: function(event) {
+ if (!this.preventInvalidInput && this.type !== 'number') {
return;
}
- this._active = this._active || {};
- if (this._active[type]) {
- this._complete(this._active[type]);
- delete this._active[type];
- }
- var activeEntries = this._configureAnimations(configs);
- if (activeEntries.length == 0) {
- this.fire('neon-animation-finish', cookie, {
- bubbles: false
- });
+ var regexp = this._patternRegExp;
+ if (!regexp) {
return;
}
- this._active[type] = activeEntries;
- for (var i = 0; i < activeEntries.length; i++) {
- activeEntries[i].animation.onfinish = function() {
- if (this._shouldComplete(activeEntries)) {
- this._complete(activeEntries);
- delete this._active[type];
- this.fire('neon-animation-finish', cookie, {
- bubbles: false
- });
- }
- }.bind(this);
+ if (event.metaKey || event.ctrlKey || event.altKey) return;
+ this._patternAlreadyChecked = true;
+ var thisChar = String.fromCharCode(event.charCode);
+ if (this._isPrintable(event) && !regexp.test(thisChar)) {
+ event.preventDefault();
+ this._announceInvalidCharacter('Invalid character ' + thisChar + ' not entered.');
}
},
- cancelAnimation: function() {
- for (var k in this._animations) {
- this._animations[k].cancel();
+ _checkPatternValidity: function() {
+ var regexp = this._patternRegExp;
+ if (!regexp) {
+ return true;
}
- this._animations = {};
- }
-};
-
-Polymer.NeonAnimationRunnerBehavior = [ Polymer.NeonAnimatableBehavior, Polymer.NeonAnimationRunnerBehaviorImpl ];
-
-Polymer.NeonAnimationBehavior = {
- properties: {
- animationTiming: {
- type: Object,
- value: function() {
- return {
- duration: 500,
- easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
- fill: 'both'
- };
+ for (var i = 0; i < this.value.length; i++) {
+ if (!regexp.test(this.value[i])) {
+ return false;
}
}
+ return true;
},
- isNeonAnimation: true,
- timingFromConfig: function(config) {
- if (config.timing) {
- for (var property in config.timing) {
- this.animationTiming[property] = config.timing[property];
+ validate: function() {
+ var valid = this.checkValidity();
+ if (valid) {
+ if (this.required && this.value === '') {
+ valid = false;
+ } else if (this.hasValidator()) {
+ valid = Polymer.IronValidatableBehavior.validate.call(this, this.value);
}
}
- return this.animationTiming;
- },
- setPrefixedProperty: function(node, property, value) {
- var map = {
- transform: [ 'webkitTransform' ],
- transformOrigin: [ 'mozTransformOrigin', 'webkitTransformOrigin' ]
- };
- var prefixes = map[property];
- for (var prefix, index = 0; prefix = prefixes[index]; index++) {
- node.style[prefix] = value;
- }
- node.style[property] = value;
- },
- complete: function() {}
-};
-
-Polymer({
- is: 'opaque-animation',
- behaviors: [ Polymer.NeonAnimationBehavior ],
- configure: function(config) {
- var node = config.node;
- this._effect = new KeyframeEffect(node, [ {
- opacity: '1'
- }, {
- opacity: '1'
- } ], this.timingFromConfig(config));
- node.style.opacity = '0';
- return this._effect;
+ this.invalid = !valid;
+ this.fire('iron-input-validate');
+ return valid;
},
- complete: function(config) {
- config.node.style.opacity = '';
+ _announceInvalidCharacter: function(message) {
+ this.fire('iron-announce', {
+ text: message
+ });
}
});
-(function() {
- 'use strict';
- var LAST_TOUCH_POSITION = {
- pageX: 0,
- pageY: 0
- };
- var ROOT_TARGET = null;
- var SCROLLABLE_NODES = [];
- Polymer.IronDropdownScrollManager = {
- get currentLockingElement() {
- return this._lockingElements[this._lockingElements.length - 1];
- },
- elementIsScrollLocked: function(element) {
- var currentLockingElement = this.currentLockingElement;
- if (currentLockingElement === undefined) return false;
- var scrollLocked;
- if (this._hasCachedLockedElement(element)) {
- return true;
- }
- if (this._hasCachedUnlockedElement(element)) {
- return false;
- }
- scrollLocked = !!currentLockingElement && currentLockingElement !== element && !this._composedTreeContains(currentLockingElement, element);
- if (scrollLocked) {
- this._lockedElementCache.push(element);
- } else {
- this._unlockedElementCache.push(element);
- }
- return scrollLocked;
- },
- pushScrollLock: function(element) {
- if (this._lockingElements.indexOf(element) >= 0) {
- return;
- }
- if (this._lockingElements.length === 0) {
- this._lockScrollInteractions();
- }
- this._lockingElements.push(element);
- this._lockedElementCache = [];
- this._unlockedElementCache = [];
+Polymer({
+ is: 'paper-input-container',
+ properties: {
+ noLabelFloat: {
+ type: Boolean,
+ value: false
},
- removeScrollLock: function(element) {
- var index = this._lockingElements.indexOf(element);
- if (index === -1) {
- return;
- }
- this._lockingElements.splice(index, 1);
- this._lockedElementCache = [];
- this._unlockedElementCache = [];
- if (this._lockingElements.length === 0) {
- this._unlockScrollInteractions();
- }
+ alwaysFloatLabel: {
+ type: Boolean,
+ value: false
},
- _lockingElements: [],
- _lockedElementCache: null,
- _unlockedElementCache: null,
- _hasCachedLockedElement: function(element) {
- return this._lockedElementCache.indexOf(element) > -1;
+ attrForValue: {
+ type: String,
+ value: 'bind-value'
},
- _hasCachedUnlockedElement: function(element) {
- return this._unlockedElementCache.indexOf(element) > -1;
+ autoValidate: {
+ type: Boolean,
+ value: false
},
- _composedTreeContains: function(element, child) {
- var contentElements;
- var distributedNodes;
- var contentIndex;
- var nodeIndex;
- if (element.contains(child)) {
- return true;
- }
- contentElements = Polymer.dom(element).querySelectorAll('content');
- for (contentIndex = 0; contentIndex < contentElements.length; ++contentIndex) {
- distributedNodes = Polymer.dom(contentElements[contentIndex]).getDistributedNodes();
- for (nodeIndex = 0; nodeIndex < distributedNodes.length; ++nodeIndex) {
- if (this._composedTreeContains(distributedNodes[nodeIndex], child)) {
- return true;
- }
- }
- }
- return false;
+ invalid: {
+ observer: '_invalidChanged',
+ type: Boolean,
+ value: false
},
- _scrollInteractionHandler: function(event) {
- if (event.cancelable && this._shouldPreventScrolling(event)) {
- event.preventDefault();
- }
- if (event.targetTouches) {
- var touch = event.targetTouches[0];
- LAST_TOUCH_POSITION.pageX = touch.pageX;
- LAST_TOUCH_POSITION.pageY = touch.pageY;
- }
+ focused: {
+ readOnly: true,
+ type: Boolean,
+ value: false,
+ notify: true
},
- _lockScrollInteractions: function() {
- this._boundScrollHandler = this._boundScrollHandler || this._scrollInteractionHandler.bind(this);
- document.addEventListener('wheel', this._boundScrollHandler, true);
- document.addEventListener('mousewheel', this._boundScrollHandler, true);
- document.addEventListener('DOMMouseScroll', this._boundScrollHandler, true);
- document.addEventListener('touchstart', this._boundScrollHandler, true);
- document.addEventListener('touchmove', this._boundScrollHandler, true);
+ _addons: {
+ type: Array
},
- _unlockScrollInteractions: function() {
- document.removeEventListener('wheel', this._boundScrollHandler, true);
- document.removeEventListener('mousewheel', this._boundScrollHandler, true);
- document.removeEventListener('DOMMouseScroll', this._boundScrollHandler, true);
- document.removeEventListener('touchstart', this._boundScrollHandler, true);
- document.removeEventListener('touchmove', this._boundScrollHandler, true);
+ _inputHasContent: {
+ type: Boolean,
+ value: false
},
- _shouldPreventScrolling: function(event) {
- var target = Polymer.dom(event).rootTarget;
- if (event.type !== 'touchmove' && ROOT_TARGET !== target) {
- ROOT_TARGET = target;
- SCROLLABLE_NODES = this._getScrollableNodes(Polymer.dom(event).path);
- }
- if (!SCROLLABLE_NODES.length) {
- return true;
+ _inputSelector: {
+ type: String,
+ value: 'input,textarea,.paper-input-input'
+ },
+ _boundOnFocus: {
+ type: Function,
+ value: function() {
+ return this._onFocus.bind(this);
}
- if (event.type === 'touchstart') {
- return false;
+ },
+ _boundOnBlur: {
+ type: Function,
+ value: function() {
+ return this._onBlur.bind(this);
}
- var info = this._getScrollInfo(event);
- return !this._getScrollingNode(SCROLLABLE_NODES, info.deltaX, info.deltaY);
},
- _getScrollableNodes: function(nodes) {
- var scrollables = [];
- var lockingIndex = nodes.indexOf(this.currentLockingElement);
- for (var i = 0; i <= lockingIndex; i++) {
- var node = nodes[i];
- if (node.nodeType === 11) {
- continue;
- }
- var style = node.style;
- if (style.overflow !== 'scroll' && style.overflow !== 'auto') {
- style = window.getComputedStyle(node);
- }
- if (style.overflow === 'scroll' || style.overflow === 'auto') {
- scrollables.push(node);
- }
+ _boundOnInput: {
+ type: Function,
+ value: function() {
+ return this._onInput.bind(this);
}
- return scrollables;
},
- _getScrollingNode: function(nodes, deltaX, deltaY) {
- if (!deltaX && !deltaY) {
- return;
+ _boundValueChanged: {
+ type: Function,
+ value: function() {
+ return this._onValueChanged.bind(this);
}
- var verticalScroll = Math.abs(deltaY) >= Math.abs(deltaX);
- for (var i = 0; i < nodes.length; i++) {
- var node = nodes[i];
- var canScroll = false;
- if (verticalScroll) {
- canScroll = deltaY < 0 ? node.scrollTop > 0 : node.scrollTop < node.scrollHeight - node.clientHeight;
- } else {
- canScroll = deltaX < 0 ? node.scrollLeft > 0 : node.scrollLeft < node.scrollWidth - node.clientWidth;
+ }
+ },
+ listeners: {
+ 'addon-attached': '_onAddonAttached',
+ 'iron-input-validate': '_onIronInputValidate'
+ },
+ get _valueChangedEvent() {
+ return this.attrForValue + '-changed';
+ },
+ get _propertyForValue() {
+ return Polymer.CaseMap.dashToCamelCase(this.attrForValue);
+ },
+ get _inputElement() {
+ return Polymer.dom(this).querySelector(this._inputSelector);
+ },
+ get _inputElementValue() {
+ return this._inputElement[this._propertyForValue] || this._inputElement.value;
+ },
+ ready: function() {
+ if (!this._addons) {
+ this._addons = [];
+ }
+ this.addEventListener('focus', this._boundOnFocus, true);
+ this.addEventListener('blur', this._boundOnBlur, true);
+ },
+ attached: function() {
+ if (this.attrForValue) {
+ this._inputElement.addEventListener(this._valueChangedEvent, this._boundValueChanged);
+ } else {
+ this.addEventListener('input', this._onInput);
+ }
+ if (this._inputElementValue != '') {
+ this._handleValueAndAutoValidate(this._inputElement);
+ } else {
+ this._handleValue(this._inputElement);
+ }
+ },
+ _onAddonAttached: function(event) {
+ if (!this._addons) {
+ this._addons = [];
+ }
+ var target = event.target;
+ if (this._addons.indexOf(target) === -1) {
+ this._addons.push(target);
+ if (this.isAttached) {
+ this._handleValue(this._inputElement);
+ }
+ }
+ },
+ _onFocus: function() {
+ this._setFocused(true);
+ },
+ _onBlur: function() {
+ this._setFocused(false);
+ this._handleValueAndAutoValidate(this._inputElement);
+ },
+ _onInput: function(event) {
+ this._handleValueAndAutoValidate(event.target);
+ },
+ _onValueChanged: function(event) {
+ this._handleValueAndAutoValidate(event.target);
+ },
+ _handleValue: function(inputElement) {
+ var value = this._inputElementValue;
+ if (value || value === 0 || inputElement.type === 'number' && !inputElement.checkValidity()) {
+ this._inputHasContent = true;
+ } else {
+ this._inputHasContent = false;
+ }
+ this.updateAddons({
+ inputElement: inputElement,
+ value: value,
+ invalid: this.invalid
+ });
+ },
+ _handleValueAndAutoValidate: function(inputElement) {
+ if (this.autoValidate) {
+ var valid;
+ if (inputElement.validate) {
+ valid = inputElement.validate(this._inputElementValue);
+ } else {
+ valid = inputElement.checkValidity();
+ }
+ this.invalid = !valid;
+ }
+ this._handleValue(inputElement);
+ },
+ _onIronInputValidate: function(event) {
+ this.invalid = this._inputElement.invalid;
+ },
+ _invalidChanged: function() {
+ if (this._addons) {
+ this.updateAddons({
+ invalid: this.invalid
+ });
+ }
+ },
+ updateAddons: function(state) {
+ for (var addon, index = 0; addon = this._addons[index]; index++) {
+ addon.update(state);
+ }
+ },
+ _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused, invalid, _inputHasContent) {
+ var cls = 'input-content';
+ if (!noLabelFloat) {
+ var label = this.querySelector('label');
+ if (alwaysFloatLabel || _inputHasContent) {
+ cls += ' label-is-floating';
+ this.$.labelAndInputContainer.style.position = 'static';
+ if (invalid) {
+ cls += ' is-invalid';
+ } else if (focused) {
+ cls += " label-is-highlighted";
}
- if (canScroll) {
- return node;
+ } else {
+ if (label) {
+ this.$.labelAndInputContainer.style.position = 'relative';
}
}
- },
- _getScrollInfo: function(event) {
- var info = {
- deltaX: event.deltaX,
- deltaY: event.deltaY
- };
- if ('deltaX' in event) {} else if ('wheelDeltaX' in event) {
- info.deltaX = -event.wheelDeltaX;
- info.deltaY = -event.wheelDeltaY;
- } else if ('axis' in event) {
- info.deltaX = event.axis === 1 ? event.detail : 0;
- info.deltaY = event.axis === 2 ? event.detail : 0;
- } else if (event.targetTouches) {
- var touch = event.targetTouches[0];
- info.deltaX = LAST_TOUCH_POSITION.pageX - touch.pageX;
- info.deltaY = LAST_TOUCH_POSITION.pageY - touch.pageY;
+ } else {
+ if (_inputHasContent) {
+ cls += ' label-is-hidden';
}
- return info;
}
- };
-})();
+ return cls;
+ },
+ _computeUnderlineClass: function(focused, invalid) {
+ var cls = 'underline';
+ if (invalid) {
+ cls += ' is-invalid';
+ } else if (focused) {
+ cls += ' is-highlighted';
+ }
+ return cls;
+ },
+ _computeAddOnContentClass: function(focused, invalid) {
+ var cls = 'add-on-content';
+ if (invalid) {
+ cls += ' is-invalid';
+ } else if (focused) {
+ cls += ' is-highlighted';
+ }
+ return cls;
+ }
+});
-(function() {
- 'use strict';
- Polymer({
- is: 'iron-dropdown',
- behaviors: [ Polymer.IronControlState, Polymer.IronA11yKeysBehavior, Polymer.IronOverlayBehavior, Polymer.NeonAnimationRunnerBehavior ],
- properties: {
- horizontalAlign: {
- type: String,
- value: 'left',
- reflectToAttribute: true
- },
- verticalAlign: {
- type: String,
- value: 'top',
- reflectToAttribute: true
- },
- openAnimationConfig: {
- type: Object
- },
- closeAnimationConfig: {
- type: Object
- },
- focusTarget: {
- type: Object
- },
- noAnimations: {
- type: Boolean,
- value: false
- },
- allowOutsideScroll: {
- type: Boolean,
- value: false
- },
- _boundOnCaptureScroll: {
- type: Function,
- value: function() {
- return this._onCaptureScroll.bind(this);
- }
- }
+Polymer.PaperSpinnerBehavior = {
+ listeners: {
+ animationend: '__reset',
+ webkitAnimationEnd: '__reset'
+ },
+ properties: {
+ active: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true,
+ observer: '__activeChanged'
},
- listeners: {
- 'neon-animation-finish': '_onNeonAnimationFinish'
+ alt: {
+ type: String,
+ value: 'loading',
+ observer: '__altChanged'
},
- observers: [ '_updateOverlayPosition(positionTarget, verticalAlign, horizontalAlign, verticalOffset, horizontalOffset)' ],
- get containedElement() {
- return Polymer.dom(this.$.content).getDistributedNodes()[0];
+ __coolingDown: {
+ type: Boolean,
+ value: false
+ }
+ },
+ __computeContainerClasses: function(active, coolingDown) {
+ return [ active || coolingDown ? 'active' : '', coolingDown ? 'cooldown' : '' ].join(' ');
+ },
+ __activeChanged: function(active, old) {
+ this.__setAriaHidden(!active);
+ this.__coolingDown = !active && old;
+ },
+ __altChanged: function(alt) {
+ if (alt === this.getPropertyInfo('alt').value) {
+ this.alt = this.getAttribute('aria-label') || alt;
+ } else {
+ this.__setAriaHidden(alt === '');
+ this.setAttribute('aria-label', alt);
+ }
+ },
+ __setAriaHidden: function(hidden) {
+ var attr = 'aria-hidden';
+ if (hidden) {
+ this.setAttribute(attr, 'true');
+ } else {
+ this.removeAttribute(attr);
+ }
+ },
+ __reset: function() {
+ this.active = false;
+ this.__coolingDown = false;
+ }
+};
+
+Polymer({
+ is: 'paper-spinner-lite',
+ behaviors: [ Polymer.PaperSpinnerBehavior ]
+});
+
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+var CrSearchFieldBehavior = {
+ properties: {
+ label: {
+ type: String,
+ value: ''
},
- get _focusTarget() {
- return this.focusTarget || this.containedElement;
+ clearLabel: {
+ type: String,
+ value: ''
},
- ready: function() {
- this._scrollTop = 0;
- this._scrollLeft = 0;
- this._refitOnScrollRAF = null;
+ showingSearch: {
+ type: Boolean,
+ value: false,
+ notify: true,
+ observer: 'showingSearchChanged_',
+ reflectToAttribute: true
},
- attached: function() {
- if (!this.sizingTarget || this.sizingTarget === this) {
- this.sizingTarget = this.containedElement;
- }
+ lastValue_: {
+ type: String,
+ value: ''
+ }
+ },
+ getSearchInput: function() {},
+ getValue: function() {
+ return this.getSearchInput().value;
+ },
+ setValue: function(value) {
+ this.getSearchInput().bindValue = value;
+ this.onValueChanged_(value);
+ },
+ showAndFocus: function() {
+ this.showingSearch = true;
+ this.focus_();
+ },
+ focus_: function() {
+ this.getSearchInput().focus();
+ },
+ onSearchTermSearch: function() {
+ this.onValueChanged_(this.getValue());
+ },
+ onValueChanged_: function(newValue) {
+ if (newValue == this.lastValue_) return;
+ this.fire('search-changed', newValue);
+ this.lastValue_ = newValue;
+ },
+ onSearchTermKeydown: function(e) {
+ if (e.key == 'Escape') this.showingSearch = false;
+ },
+ showingSearchChanged_: function() {
+ if (this.showingSearch) {
+ this.focus_();
+ return;
+ }
+ this.setValue('');
+ this.getSearchInput().blur();
+ }
+};
+
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+Polymer({
+ is: 'cr-toolbar-search-field',
+ behaviors: [ CrSearchFieldBehavior ],
+ properties: {
+ narrow: {
+ type: Boolean,
+ reflectToAttribute: true
},
- detached: function() {
- this.cancelAnimation();
- document.removeEventListener('scroll', this._boundOnCaptureScroll);
- Polymer.IronDropdownScrollManager.removeScrollLock(this);
+ label: String,
+ clearLabel: String,
+ spinnerActive: {
+ type: Boolean,
+ reflectToAttribute: true
},
- _openedChanged: function() {
- if (this.opened && this.disabled) {
- this.cancel();
- } else {
- this.cancelAnimation();
- this._updateAnimationConfig();
- this._saveScrollPosition();
- if (this.opened) {
- document.addEventListener('scroll', this._boundOnCaptureScroll);
- !this.allowOutsideScroll && Polymer.IronDropdownScrollManager.pushScrollLock(this);
- } else {
- document.removeEventListener('scroll', this._boundOnCaptureScroll);
- Polymer.IronDropdownScrollManager.removeScrollLock(this);
- }
- Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this, arguments);
- }
+ hasSearchText_: Boolean,
+ isSpinnerShown_: {
+ type: Boolean,
+ computed: 'computeIsSpinnerShown_(spinnerActive, showingSearch)'
+ }
+ },
+ listeners: {
+ tap: 'showSearch_',
+ 'searchInput.bind-value-changed': 'onBindValueChanged_'
+ },
+ getSearchInput: function() {
+ return this.$.searchInput;
+ },
+ isSearchFocused: function() {
+ return this.$.searchTerm.focused;
+ },
+ computeIconTabIndex_: function(narrow) {
+ return narrow ? 0 : -1;
+ },
+ computeIsSpinnerShown_: function() {
+ return this.spinnerActive && this.showingSearch;
+ },
+ onInputBlur_: function() {
+ if (!this.hasSearchText_) this.showingSearch = false;
+ },
+ onBindValueChanged_: function() {
+ var newValue = this.$.searchInput.bindValue;
+ this.hasSearchText_ = newValue != '';
+ if (newValue != '') this.showingSearch = true;
+ },
+ showSearch_: function(e) {
+ if (e.target != this.$.clearSearch) this.showingSearch = true;
+ },
+ hideSearch_: function(e) {
+ this.showingSearch = false;
+ e.stopPropagation();
+ }
+});
+
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+Polymer({
+ is: 'cr-toolbar',
+ properties: {
+ pageName: String,
+ searchPrompt: String,
+ clearLabel: String,
+ menuLabel: String,
+ spinnerActive: Boolean,
+ showMenu: {
+ type: Boolean,
+ value: false
},
- _renderOpened: function() {
- if (!this.noAnimations && this.animationConfig.open) {
- this.$.contentWrapper.classList.add('animating');
- this.playAnimation('open');
- } else {
- Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this, arguments);
- }
+ narrow_: {
+ type: Boolean,
+ reflectToAttribute: true
},
- _renderClosed: function() {
- if (!this.noAnimations && this.animationConfig.close) {
- this.$.contentWrapper.classList.add('animating');
- this.playAnimation('close');
- } else {
- Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this, arguments);
+ showingSearch_: {
+ type: Boolean,
+ reflectToAttribute: true
+ }
+ },
+ getSearchField: function() {
+ return this.$.search;
+ },
+ onMenuTap_: function(e) {
+ this.fire('cr-menu-tap');
+ }
+});
+
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+Polymer({
+ is: 'history-lazy-render',
+ "extends": 'template',
+ behaviors: [ Polymer.Templatizer ],
+ _renderPromise: null,
+ _instance: null,
+ get: function() {
+ if (!this._renderPromise) {
+ this._renderPromise = new Promise(function(resolve) {
+ this._debounceTemplate(function() {
+ this._render();
+ this._renderPromise = null;
+ resolve(this.getIfExists());
+ }.bind(this));
+ }.bind(this));
+ }
+ return this._renderPromise;
+ },
+ getIfExists: function() {
+ if (this._instance) {
+ var children = this._instance._children;
+ for (var i = 0; i < children.length; i++) {
+ if (children[i].nodeType == Node.ELEMENT_NODE) return children[i];
}
+ }
+ return null;
+ },
+ _render: function() {
+ if (!this.ctor) this.templatize(this);
+ var parentNode = this.parentNode;
+ if (parentNode && !this._instance) {
+ this._instance = this.stamp({});
+ var root = this._instance.root;
+ parentNode.insertBefore(root, this);
+ }
+ },
+ _forwardParentProp: function(prop, value) {
+ if (this._instance) this._instance.__setProperty(prop, value, true);
+ },
+ _forwardParentPath: function(path, value) {
+ if (this._instance) this._instance._notifyPath(path, value, true);
+ }
+});
+
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+Polymer({
+ is: 'history-toolbar',
+ properties: {
+ count: {
+ type: Number,
+ value: 0,
+ observer: 'changeToolbarView_'
},
- _onNeonAnimationFinish: function() {
- this.$.contentWrapper.classList.remove('animating');
- if (this.opened) {
- this._finishRenderOpened();
- } else {
- this._finishRenderClosed();
- }
+ itemsSelected_: {
+ type: Boolean,
+ value: false,
+ reflectToAttribute: true
},
- _onCaptureScroll: function() {
- if (!this.allowOutsideScroll) {
- this._restoreScrollPosition();
- } else {
- this._refitOnScrollRAF && window.cancelAnimationFrame(this._refitOnScrollRAF);
- this._refitOnScrollRAF = window.requestAnimationFrame(this.refit.bind(this));
- }
+ searchTerm: {
+ type: String,
+ notify: true
},
- _saveScrollPosition: function() {
- if (document.scrollingElement) {
- this._scrollTop = document.scrollingElement.scrollTop;
- this._scrollLeft = document.scrollingElement.scrollLeft;
- } else {
- this._scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
- this._scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
- }
+ spinnerActive: {
+ type: Boolean,
+ value: false
},
- _restoreScrollPosition: function() {
- if (document.scrollingElement) {
- document.scrollingElement.scrollTop = this._scrollTop;
- document.scrollingElement.scrollLeft = this._scrollLeft;
- } else {
- document.documentElement.scrollTop = this._scrollTop;
- document.documentElement.scrollLeft = this._scrollLeft;
- document.body.scrollTop = this._scrollTop;
- document.body.scrollLeft = this._scrollLeft;
- }
+ hasDrawer: {
+ type: Boolean,
+ observer: 'hasDrawerChanged_',
+ reflectToAttribute: true
},
- _updateAnimationConfig: function() {
- var animations = (this.openAnimationConfig || []).concat(this.closeAnimationConfig || []);
- for (var i = 0; i < animations.length; i++) {
- animations[i].node = this.containedElement;
- }
- this.animationConfig = {
- open: this.openAnimationConfig,
- close: this.closeAnimationConfig
- };
+ showSyncNotice: Boolean,
+ isGroupedMode: {
+ type: Boolean,
+ reflectToAttribute: true
},
- _updateOverlayPosition: function() {
- if (this.isAttached) {
- this.notifyResize();
- }
+ groupedRange: {
+ type: Number,
+ value: 0,
+ reflectToAttribute: true,
+ notify: true
},
- _applyFocus: function() {
- var focusTarget = this.focusTarget || this.containedElement;
- if (focusTarget && this.opened && !this.noAutoFocus) {
- focusTarget.focus();
- } else {
- Polymer.IronOverlayBehaviorImpl._applyFocus.apply(this, arguments);
- }
- }
- });
-})();
+ queryStartTime: String,
+ queryEndTime: String
+ },
+ changeToolbarView_: function() {
+ this.itemsSelected_ = this.count > 0;
+ },
+ setSearchTerm: function(search) {
+ if (this.searchTerm == search) return;
+ this.searchTerm = search;
+ var searchField = this.$['main-toolbar'].getSearchField();
+ searchField.showAndFocus();
+ searchField.setValue(search);
+ },
+ onSearchChanged_: function(event) {
+ this.searchTerm = event.detail;
+ },
+ onInfoButtonTap_: function() {
+ this.$.syncNotice.get().then(function(dropdown) {
+ dropdown.positionTarget = this.$$('#info-button-icon');
+ if (dropdown.style.display == 'none') dropdown.open();
+ }.bind(this));
+ },
+ onClearSelectionTap_: function() {
+ this.fire('unselect-all');
+ },
+ onDeleteTap_: function() {
+ this.fire('delete-selected');
+ },
+ get searchBar() {
+ return this.$['main-toolbar'].getSearchField();
+ },
+ showSearchField: function() {
+ this.$['main-toolbar'].getSearchField().showAndFocus();
+ },
+ deletingAllowed_: function() {
+ return loadTimeData.getBoolean('allowDeletingHistory');
+ },
+ numberOfItemsSelected_: function(count) {
+ return count > 0 ? loadTimeData.getStringF('itemsSelected', count) : '';
+ },
+ getHistoryInterval_: function(queryStartTime, queryEndTime) {
+ return loadTimeData.getStringF('historyInterval', queryStartTime, queryEndTime);
+ },
+ hasDrawerChanged_: function() {
+ this.updateStyles();
+ }
+});
+
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+Polymer({
+ is: 'cr-dialog',
+ "extends": 'dialog',
+ created: function() {
+ window.addEventListener('popstate', function() {
+ if (this.open) this.cancel();
+ }.bind(this));
+ },
+ cancel: function() {
+ this.fire('cancel');
+ HTMLDialogElement.prototype.close.call(this, '');
+ },
+ close: function(opt_returnValue) {
+ HTMLDialogElement.prototype.close.call(this, 'success');
+ },
+ getCloseButton: function() {
+ return this.$.close;
+ }
+});
Polymer({
is: 'fade-in-animation',
@@ -6536,32 +6616,6 @@ Polymer({
}
});
-Polymer({
- is: 'paper-icon-button-light',
- "extends": 'button',
- behaviors: [ Polymer.PaperRippleBehavior ],
- listeners: {
- down: '_rippleDown',
- up: '_rippleUp',
- focus: '_rippleDown',
- blur: '_rippleUp'
- },
- _rippleDown: function() {
- this.getRipple().downAction();
- },
- _rippleUp: function() {
- this.getRipple().upAction();
- },
- ensureRipple: function(var_args) {
- var lastRipple = this._ripple;
- Polymer.PaperRippleBehavior.ensureRipple.apply(this, arguments);
- if (this._ripple && this._ripple !== lastRipple) {
- this._ripple.center = true;
- this._ripple.classList.add('circle');
- }
- }
-});
-
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8019,53 +8073,6 @@ Polymer({
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Polymer({
- is: 'history-lazy-render',
- "extends": 'template',
- behaviors: [ Polymer.Templatizer ],
- _renderPromise: null,
- _instance: null,
- get: function() {
- if (!this._renderPromise) {
- this._renderPromise = new Promise(function(resolve) {
- this._debounceTemplate(function() {
- this._render();
- this._renderPromise = null;
- resolve(this.getIfExists());
- }.bind(this));
- }.bind(this));
- }
- return this._renderPromise;
- },
- getIfExists: function() {
- if (this._instance) {
- var children = this._instance._children;
- for (var i = 0; i < children.length; i++) {
- if (children[i].nodeType == Node.ELEMENT_NODE) return children[i];
- }
- }
- return null;
- },
- _render: function() {
- if (!this.ctor) this.templatize(this);
- var parentNode = this.parentNode;
- if (parentNode && !this._instance) {
- this._instance = this.stamp({});
- var root = this._instance.root;
- parentNode.insertBefore(root, this);
- }
- },
- _forwardParentProp: function(prop, value) {
- if (this._instance) this._instance.__setProperty(prop, value, true);
- },
- _forwardParentPath: function(path, value) {
- if (this._instance) this._instance._notifyPath(path, value, true);
- }
-});
-
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-Polymer({
is: 'history-list-container',
properties: {
selectedPage_: String,
@@ -8488,6 +8495,7 @@ Polymer({
behaviors: [ Polymer.IronScrollTargetBehavior ],
properties: {
showSidebarFooter: Boolean,
+ hasSyncedResults: Boolean,
selectedPage_: {
type: String,
observer: 'unselectAll'
@@ -8646,6 +8654,9 @@ Polymer({
shouldShowSpinner_: function(querying, incremental, searchTerm) {
return querying && !incremental && searchTerm != '';
},
+ showSyncNotice_: function(hasSyncedResults, selectedPage) {
+ return hasSyncedResults && selectedPage != 'syncedTabs';
+ },
routeDataChanged_: function(page) {
this.selectedPage_ = page;
},
« no previous file with comments | « chrome/browser/resources/md_history/app.js ('k') | chrome/browser/resources/md_history/app.vulcanized.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698