| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 function PromiseResolver() { | 4 function PromiseResolver() { |
| 5 this.resolve_; | 5 this.resolve_; |
| 6 this.reject_; | 6 this.reject_; |
| 7 this.promise_ = new Promise(function(resolve, reject) { | 7 this.promise_ = new Promise(function(resolve, reject) { |
| 8 this.resolve_ = resolve; | 8 this.resolve_ = resolve; |
| 9 this.reject_ = reject; | 9 this.reject_ = reject; |
| 10 }.bind(this)); | 10 }.bind(this)); |
| (...skipping 2247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2258 this.tabIndex = this._oldTabIndex; | 2258 this.tabIndex = this._oldTabIndex; |
| 2259 } | 2259 } |
| 2260 }, | 2260 }, |
| 2261 _changedControlState: function() { | 2261 _changedControlState: function() { |
| 2262 if (this._controlStateChanged) { | 2262 if (this._controlStateChanged) { |
| 2263 this._controlStateChanged(); | 2263 this._controlStateChanged(); |
| 2264 } | 2264 } |
| 2265 } | 2265 } |
| 2266 }; | 2266 }; |
| 2267 | 2267 |
| 2268 Polymer.IronButtonStateImpl = { | 2268 Polymer.IronFitBehavior = { |
| 2269 properties: { | 2269 properties: { |
| 2270 pressed: { | 2270 sizingTarget: { |
| 2271 type: Object, |
| 2272 value: function() { |
| 2273 return this; |
| 2274 } |
| 2275 }, |
| 2276 fitInto: { |
| 2277 type: Object, |
| 2278 value: window |
| 2279 }, |
| 2280 noOverlap: { |
| 2281 type: Boolean |
| 2282 }, |
| 2283 positionTarget: { |
| 2284 type: Element |
| 2285 }, |
| 2286 horizontalAlign: { |
| 2287 type: String |
| 2288 }, |
| 2289 verticalAlign: { |
| 2290 type: String |
| 2291 }, |
| 2292 dynamicAlign: { |
| 2293 type: Boolean |
| 2294 }, |
| 2295 horizontalOffset: { |
| 2296 type: Number, |
| 2297 value: 0, |
| 2298 notify: true |
| 2299 }, |
| 2300 verticalOffset: { |
| 2301 type: Number, |
| 2302 value: 0, |
| 2303 notify: true |
| 2304 }, |
| 2305 autoFitOnAttach: { |
| 2271 type: Boolean, | 2306 type: Boolean, |
| 2272 readOnly: true, | |
| 2273 value: false, | |
| 2274 reflectToAttribute: true, | |
| 2275 observer: '_pressedChanged' | |
| 2276 }, | |
| 2277 toggles: { | |
| 2278 type: Boolean, | |
| 2279 value: false, | |
| 2280 reflectToAttribute: true | |
| 2281 }, | |
| 2282 active: { | |
| 2283 type: Boolean, | |
| 2284 value: false, | |
| 2285 notify: true, | |
| 2286 reflectToAttribute: true | |
| 2287 }, | |
| 2288 pointerDown: { | |
| 2289 type: Boolean, | |
| 2290 readOnly: true, | |
| 2291 value: false | 2307 value: false |
| 2292 }, | 2308 }, |
| 2293 receivedFocusFromKeyboard: { | 2309 _fitInfo: { |
| 2294 type: Boolean, | 2310 type: Object |
| 2295 readOnly: true | 2311 } |
| 2296 }, | 2312 }, |
| 2297 ariaActiveAttribute: { | 2313 get _fitWidth() { |
| 2298 type: String, | 2314 var fitWidth; |
| 2299 value: 'aria-pressed', | 2315 if (this.fitInto === window) { |
| 2300 observer: '_ariaActiveAttributeChanged' | 2316 fitWidth = this.fitInto.innerWidth; |
| 2301 } | |
| 2302 }, | |
| 2303 listeners: { | |
| 2304 down: '_downHandler', | |
| 2305 up: '_upHandler', | |
| 2306 tap: '_tapHandler' | |
| 2307 }, | |
| 2308 observers: [ '_detectKeyboardFocus(focused)', '_activeChanged(active, ariaActi
veAttribute)' ], | |
| 2309 keyBindings: { | |
| 2310 'enter:keydown': '_asyncClick', | |
| 2311 'space:keydown': '_spaceKeyDownHandler', | |
| 2312 'space:keyup': '_spaceKeyUpHandler' | |
| 2313 }, | |
| 2314 _mouseEventRe: /^mouse/, | |
| 2315 _tapHandler: function() { | |
| 2316 if (this.toggles) { | |
| 2317 this._userActivate(!this.active); | |
| 2318 } else { | 2317 } else { |
| 2319 this.active = false; | 2318 fitWidth = this.fitInto.getBoundingClientRect().width; |
| 2320 } | 2319 } |
| 2321 }, | 2320 return fitWidth; |
| 2322 _detectKeyboardFocus: function(focused) { | 2321 }, |
| 2323 this._setReceivedFocusFromKeyboard(!this.pointerDown && focused); | 2322 get _fitHeight() { |
| 2324 }, | 2323 var fitHeight; |
| 2325 _userActivate: function(active) { | 2324 if (this.fitInto === window) { |
| 2326 if (this.active !== active) { | 2325 fitHeight = this.fitInto.innerHeight; |
| 2327 this.active = active; | |
| 2328 this.fire('change'); | |
| 2329 } | |
| 2330 }, | |
| 2331 _downHandler: function(event) { | |
| 2332 this._setPointerDown(true); | |
| 2333 this._setPressed(true); | |
| 2334 this._setReceivedFocusFromKeyboard(false); | |
| 2335 }, | |
| 2336 _upHandler: function() { | |
| 2337 this._setPointerDown(false); | |
| 2338 this._setPressed(false); | |
| 2339 }, | |
| 2340 _spaceKeyDownHandler: function(event) { | |
| 2341 var keyboardEvent = event.detail.keyboardEvent; | |
| 2342 var target = Polymer.dom(keyboardEvent).localTarget; | |
| 2343 if (this.isLightDescendant(target)) return; | |
| 2344 keyboardEvent.preventDefault(); | |
| 2345 keyboardEvent.stopImmediatePropagation(); | |
| 2346 this._setPressed(true); | |
| 2347 }, | |
| 2348 _spaceKeyUpHandler: function(event) { | |
| 2349 var keyboardEvent = event.detail.keyboardEvent; | |
| 2350 var target = Polymer.dom(keyboardEvent).localTarget; | |
| 2351 if (this.isLightDescendant(target)) return; | |
| 2352 if (this.pressed) { | |
| 2353 this._asyncClick(); | |
| 2354 } | |
| 2355 this._setPressed(false); | |
| 2356 }, | |
| 2357 _asyncClick: function() { | |
| 2358 this.async(function() { | |
| 2359 this.click(); | |
| 2360 }, 1); | |
| 2361 }, | |
| 2362 _pressedChanged: function(pressed) { | |
| 2363 this._changedButtonState(); | |
| 2364 }, | |
| 2365 _ariaActiveAttributeChanged: function(value, oldValue) { | |
| 2366 if (oldValue && oldValue != value && this.hasAttribute(oldValue)) { | |
| 2367 this.removeAttribute(oldValue); | |
| 2368 } | |
| 2369 }, | |
| 2370 _activeChanged: function(active, ariaActiveAttribute) { | |
| 2371 if (this.toggles) { | |
| 2372 this.setAttribute(this.ariaActiveAttribute, active ? 'true' : 'false'); | |
| 2373 } else { | 2326 } else { |
| 2374 this.removeAttribute(this.ariaActiveAttribute); | 2327 fitHeight = this.fitInto.getBoundingClientRect().height; |
| 2375 } | 2328 } |
| 2376 this._changedButtonState(); | 2329 return fitHeight; |
| 2377 }, | 2330 }, |
| 2378 _controlStateChanged: function() { | 2331 get _fitLeft() { |
| 2379 if (this.disabled) { | 2332 var fitLeft; |
| 2380 this._setPressed(false); | 2333 if (this.fitInto === window) { |
| 2334 fitLeft = 0; |
| 2381 } else { | 2335 } else { |
| 2382 this._changedButtonState(); | 2336 fitLeft = this.fitInto.getBoundingClientRect().left; |
| 2383 } | 2337 } |
| 2384 }, | 2338 return fitLeft; |
| 2385 _changedButtonState: function() { | 2339 }, |
| 2386 if (this._buttonStateChanged) { | 2340 get _fitTop() { |
| 2387 this._buttonStateChanged(); | 2341 var fitTop; |
| 2388 } | 2342 if (this.fitInto === window) { |
| 2343 fitTop = 0; |
| 2344 } else { |
| 2345 fitTop = this.fitInto.getBoundingClientRect().top; |
| 2346 } |
| 2347 return fitTop; |
| 2348 }, |
| 2349 get _defaultPositionTarget() { |
| 2350 var parent = Polymer.dom(this).parentNode; |
| 2351 if (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { |
| 2352 parent = parent.host; |
| 2353 } |
| 2354 return parent; |
| 2355 }, |
| 2356 get _localeHorizontalAlign() { |
| 2357 if (this._isRTL) { |
| 2358 if (this.horizontalAlign === 'right') { |
| 2359 return 'left'; |
| 2360 } |
| 2361 if (this.horizontalAlign === 'left') { |
| 2362 return 'right'; |
| 2363 } |
| 2364 } |
| 2365 return this.horizontalAlign; |
| 2366 }, |
| 2367 attached: function() { |
| 2368 this._isRTL = window.getComputedStyle(this).direction == 'rtl'; |
| 2369 this.positionTarget = this.positionTarget || this._defaultPositionTarget; |
| 2370 if (this.autoFitOnAttach) { |
| 2371 if (window.getComputedStyle(this).display === 'none') { |
| 2372 setTimeout(function() { |
| 2373 this.fit(); |
| 2374 }.bind(this)); |
| 2375 } else { |
| 2376 this.fit(); |
| 2377 } |
| 2378 } |
| 2379 }, |
| 2380 fit: function() { |
| 2381 this.position(); |
| 2382 this.constrain(); |
| 2383 this.center(); |
| 2384 }, |
| 2385 _discoverInfo: function() { |
| 2386 if (this._fitInfo) { |
| 2387 return; |
| 2388 } |
| 2389 var target = window.getComputedStyle(this); |
| 2390 var sizer = window.getComputedStyle(this.sizingTarget); |
| 2391 this._fitInfo = { |
| 2392 inlineStyle: { |
| 2393 top: this.style.top || '', |
| 2394 left: this.style.left || '', |
| 2395 position: this.style.position || '' |
| 2396 }, |
| 2397 sizerInlineStyle: { |
| 2398 maxWidth: this.sizingTarget.style.maxWidth || '', |
| 2399 maxHeight: this.sizingTarget.style.maxHeight || '', |
| 2400 boxSizing: this.sizingTarget.style.boxSizing || '' |
| 2401 }, |
| 2402 positionedBy: { |
| 2403 vertically: target.top !== 'auto' ? 'top' : target.bottom !== 'auto' ? '
bottom' : null, |
| 2404 horizontally: target.left !== 'auto' ? 'left' : target.right !== 'auto'
? 'right' : null |
| 2405 }, |
| 2406 sizedBy: { |
| 2407 height: sizer.maxHeight !== 'none', |
| 2408 width: sizer.maxWidth !== 'none', |
| 2409 minWidth: parseInt(sizer.minWidth, 10) || 0, |
| 2410 minHeight: parseInt(sizer.minHeight, 10) || 0 |
| 2411 }, |
| 2412 margin: { |
| 2413 top: parseInt(target.marginTop, 10) || 0, |
| 2414 right: parseInt(target.marginRight, 10) || 0, |
| 2415 bottom: parseInt(target.marginBottom, 10) || 0, |
| 2416 left: parseInt(target.marginLeft, 10) || 0 |
| 2417 } |
| 2418 }; |
| 2419 if (this.verticalOffset) { |
| 2420 this._fitInfo.margin.top = this._fitInfo.margin.bottom = this.verticalOffs
et; |
| 2421 this._fitInfo.inlineStyle.marginTop = this.style.marginTop || ''; |
| 2422 this._fitInfo.inlineStyle.marginBottom = this.style.marginBottom || ''; |
| 2423 this.style.marginTop = this.style.marginBottom = this.verticalOffset + 'px
'; |
| 2424 } |
| 2425 if (this.horizontalOffset) { |
| 2426 this._fitInfo.margin.left = this._fitInfo.margin.right = this.horizontalOf
fset; |
| 2427 this._fitInfo.inlineStyle.marginLeft = this.style.marginLeft || ''; |
| 2428 this._fitInfo.inlineStyle.marginRight = this.style.marginRight || ''; |
| 2429 this.style.marginLeft = this.style.marginRight = this.horizontalOffset + '
px'; |
| 2430 } |
| 2431 }, |
| 2432 resetFit: function() { |
| 2433 var info = this._fitInfo || {}; |
| 2434 for (var property in info.sizerInlineStyle) { |
| 2435 this.sizingTarget.style[property] = info.sizerInlineStyle[property]; |
| 2436 } |
| 2437 for (var property in info.inlineStyle) { |
| 2438 this.style[property] = info.inlineStyle[property]; |
| 2439 } |
| 2440 this._fitInfo = null; |
| 2441 }, |
| 2442 refit: function() { |
| 2443 var scrollLeft = this.sizingTarget.scrollLeft; |
| 2444 var scrollTop = this.sizingTarget.scrollTop; |
| 2445 this.resetFit(); |
| 2446 this.fit(); |
| 2447 this.sizingTarget.scrollLeft = scrollLeft; |
| 2448 this.sizingTarget.scrollTop = scrollTop; |
| 2449 }, |
| 2450 position: function() { |
| 2451 if (!this.horizontalAlign && !this.verticalAlign) { |
| 2452 return; |
| 2453 } |
| 2454 this._discoverInfo(); |
| 2455 this.style.position = 'fixed'; |
| 2456 this.sizingTarget.style.boxSizing = 'border-box'; |
| 2457 this.style.left = '0px'; |
| 2458 this.style.top = '0px'; |
| 2459 var rect = this.getBoundingClientRect(); |
| 2460 var positionRect = this.__getNormalizedRect(this.positionTarget); |
| 2461 var fitRect = this.__getNormalizedRect(this.fitInto); |
| 2462 var margin = this._fitInfo.margin; |
| 2463 var size = { |
| 2464 width: rect.width + margin.left + margin.right, |
| 2465 height: rect.height + margin.top + margin.bottom |
| 2466 }; |
| 2467 var position = this.__getPosition(this._localeHorizontalAlign, this.vertical
Align, size, positionRect, fitRect); |
| 2468 var left = position.left + margin.left; |
| 2469 var top = position.top + margin.top; |
| 2470 var right = Math.min(fitRect.right - margin.right, left + rect.width); |
| 2471 var bottom = Math.min(fitRect.bottom - margin.bottom, top + rect.height); |
| 2472 var minWidth = this._fitInfo.sizedBy.minWidth; |
| 2473 var minHeight = this._fitInfo.sizedBy.minHeight; |
| 2474 if (left < margin.left) { |
| 2475 left = margin.left; |
| 2476 if (right - left < minWidth) { |
| 2477 left = right - minWidth; |
| 2478 } |
| 2479 } |
| 2480 if (top < margin.top) { |
| 2481 top = margin.top; |
| 2482 if (bottom - top < minHeight) { |
| 2483 top = bottom - minHeight; |
| 2484 } |
| 2485 } |
| 2486 this.sizingTarget.style.maxWidth = right - left + 'px'; |
| 2487 this.sizingTarget.style.maxHeight = bottom - top + 'px'; |
| 2488 this.style.left = left - rect.left + 'px'; |
| 2489 this.style.top = top - rect.top + 'px'; |
| 2490 }, |
| 2491 constrain: function() { |
| 2492 if (this.horizontalAlign || this.verticalAlign) { |
| 2493 return; |
| 2494 } |
| 2495 this._discoverInfo(); |
| 2496 var info = this._fitInfo; |
| 2497 if (!info.positionedBy.vertically) { |
| 2498 this.style.position = 'fixed'; |
| 2499 this.style.top = '0px'; |
| 2500 } |
| 2501 if (!info.positionedBy.horizontally) { |
| 2502 this.style.position = 'fixed'; |
| 2503 this.style.left = '0px'; |
| 2504 } |
| 2505 this.sizingTarget.style.boxSizing = 'border-box'; |
| 2506 var rect = this.getBoundingClientRect(); |
| 2507 if (!info.sizedBy.height) { |
| 2508 this.__sizeDimension(rect, info.positionedBy.vertically, 'top', 'bottom',
'Height'); |
| 2509 } |
| 2510 if (!info.sizedBy.width) { |
| 2511 this.__sizeDimension(rect, info.positionedBy.horizontally, 'left', 'right'
, 'Width'); |
| 2512 } |
| 2513 }, |
| 2514 _sizeDimension: function(rect, positionedBy, start, end, extent) { |
| 2515 this.__sizeDimension(rect, positionedBy, start, end, extent); |
| 2516 }, |
| 2517 __sizeDimension: function(rect, positionedBy, start, end, extent) { |
| 2518 var info = this._fitInfo; |
| 2519 var fitRect = this.__getNormalizedRect(this.fitInto); |
| 2520 var max = extent === 'Width' ? fitRect.width : fitRect.height; |
| 2521 var flip = positionedBy === end; |
| 2522 var offset = flip ? max - rect[end] : rect[start]; |
| 2523 var margin = info.margin[flip ? start : end]; |
| 2524 var offsetExtent = 'offset' + extent; |
| 2525 var sizingOffset = this[offsetExtent] - this.sizingTarget[offsetExtent]; |
| 2526 this.sizingTarget.style['max' + extent] = max - margin - offset - sizingOffs
et + 'px'; |
| 2527 }, |
| 2528 center: function() { |
| 2529 if (this.horizontalAlign || this.verticalAlign) { |
| 2530 return; |
| 2531 } |
| 2532 this._discoverInfo(); |
| 2533 var positionedBy = this._fitInfo.positionedBy; |
| 2534 if (positionedBy.vertically && positionedBy.horizontally) { |
| 2535 return; |
| 2536 } |
| 2537 this.style.position = 'fixed'; |
| 2538 if (!positionedBy.vertically) { |
| 2539 this.style.top = '0px'; |
| 2540 } |
| 2541 if (!positionedBy.horizontally) { |
| 2542 this.style.left = '0px'; |
| 2543 } |
| 2544 var rect = this.getBoundingClientRect(); |
| 2545 var fitRect = this.__getNormalizedRect(this.fitInto); |
| 2546 if (!positionedBy.vertically) { |
| 2547 var top = fitRect.top - rect.top + (fitRect.height - rect.height) / 2; |
| 2548 this.style.top = top + 'px'; |
| 2549 } |
| 2550 if (!positionedBy.horizontally) { |
| 2551 var left = fitRect.left - rect.left + (fitRect.width - rect.width) / 2; |
| 2552 this.style.left = left + 'px'; |
| 2553 } |
| 2554 }, |
| 2555 __getNormalizedRect: function(target) { |
| 2556 if (target === document.documentElement || target === window) { |
| 2557 return { |
| 2558 top: 0, |
| 2559 left: 0, |
| 2560 width: window.innerWidth, |
| 2561 height: window.innerHeight, |
| 2562 right: window.innerWidth, |
| 2563 bottom: window.innerHeight |
| 2564 }; |
| 2565 } |
| 2566 return target.getBoundingClientRect(); |
| 2567 }, |
| 2568 __getCroppedArea: function(position, size, fitRect) { |
| 2569 var verticalCrop = Math.min(0, position.top) + Math.min(0, fitRect.bottom -
(position.top + size.height)); |
| 2570 var horizontalCrop = Math.min(0, position.left) + Math.min(0, fitRect.right
- (position.left + size.width)); |
| 2571 return Math.abs(verticalCrop) * size.width + Math.abs(horizontalCrop) * size
.height; |
| 2572 }, |
| 2573 __getPosition: function(hAlign, vAlign, size, positionRect, fitRect) { |
| 2574 var positions = [ { |
| 2575 verticalAlign: 'top', |
| 2576 horizontalAlign: 'left', |
| 2577 top: positionRect.top, |
| 2578 left: positionRect.left |
| 2579 }, { |
| 2580 verticalAlign: 'top', |
| 2581 horizontalAlign: 'right', |
| 2582 top: positionRect.top, |
| 2583 left: positionRect.right - size.width |
| 2584 }, { |
| 2585 verticalAlign: 'bottom', |
| 2586 horizontalAlign: 'left', |
| 2587 top: positionRect.bottom - size.height, |
| 2588 left: positionRect.left |
| 2589 }, { |
| 2590 verticalAlign: 'bottom', |
| 2591 horizontalAlign: 'right', |
| 2592 top: positionRect.bottom - size.height, |
| 2593 left: positionRect.right - size.width |
| 2594 } ]; |
| 2595 if (this.noOverlap) { |
| 2596 for (var i = 0, l = positions.length; i < l; i++) { |
| 2597 var copy = {}; |
| 2598 for (var key in positions[i]) { |
| 2599 copy[key] = positions[i][key]; |
| 2600 } |
| 2601 positions.push(copy); |
| 2602 } |
| 2603 positions[0].top = positions[1].top += positionRect.height; |
| 2604 positions[2].top = positions[3].top -= positionRect.height; |
| 2605 positions[4].left = positions[6].left += positionRect.width; |
| 2606 positions[5].left = positions[7].left -= positionRect.width; |
| 2607 } |
| 2608 vAlign = vAlign === 'auto' ? null : vAlign; |
| 2609 hAlign = hAlign === 'auto' ? null : hAlign; |
| 2610 var position; |
| 2611 for (var i = 0; i < positions.length; i++) { |
| 2612 var pos = positions[i]; |
| 2613 if (!this.dynamicAlign && !this.noOverlap && pos.verticalAlign === vAlign
&& pos.horizontalAlign === hAlign) { |
| 2614 position = pos; |
| 2615 break; |
| 2616 } |
| 2617 var alignOk = (!vAlign || pos.verticalAlign === vAlign) && (!hAlign || pos
.horizontalAlign === hAlign); |
| 2618 if (!this.dynamicAlign && !alignOk) { |
| 2619 continue; |
| 2620 } |
| 2621 position = position || pos; |
| 2622 pos.croppedArea = this.__getCroppedArea(pos, size, fitRect); |
| 2623 var diff = pos.croppedArea - position.croppedArea; |
| 2624 if (diff < 0 || diff === 0 && alignOk) { |
| 2625 position = pos; |
| 2626 } |
| 2627 if (position.croppedArea === 0 && alignOk) { |
| 2628 break; |
| 2629 } |
| 2630 } |
| 2631 return position; |
| 2389 } | 2632 } |
| 2390 }; | 2633 }; |
| 2391 | 2634 |
| 2392 Polymer.IronButtonState = [ Polymer.IronA11yKeysBehavior, Polymer.IronButtonStat
eImpl ]; | |
| 2393 | |
| 2394 (function() { | 2635 (function() { |
| 2395 var Utility = { | 2636 'use strict'; |
| 2396 distance: function(x1, y1, x2, y2) { | |
| 2397 var xDelta = x1 - x2; | |
| 2398 var yDelta = y1 - y2; | |
| 2399 return Math.sqrt(xDelta * xDelta + yDelta * yDelta); | |
| 2400 }, | |
| 2401 now: window.performance && window.performance.now ? window.performance.now.b
ind(window.performance) : Date.now | |
| 2402 }; | |
| 2403 function ElementMetrics(element) { | |
| 2404 this.element = element; | |
| 2405 this.width = this.boundingRect.width; | |
| 2406 this.height = this.boundingRect.height; | |
| 2407 this.size = Math.max(this.width, this.height); | |
| 2408 } | |
| 2409 ElementMetrics.prototype = { | |
| 2410 get boundingRect() { | |
| 2411 return this.element.getBoundingClientRect(); | |
| 2412 }, | |
| 2413 furthestCornerDistanceFrom: function(x, y) { | |
| 2414 var topLeft = Utility.distance(x, y, 0, 0); | |
| 2415 var topRight = Utility.distance(x, y, this.width, 0); | |
| 2416 var bottomLeft = Utility.distance(x, y, 0, this.height); | |
| 2417 var bottomRight = Utility.distance(x, y, this.width, this.height); | |
| 2418 return Math.max(topLeft, topRight, bottomLeft, bottomRight); | |
| 2419 } | |
| 2420 }; | |
| 2421 function Ripple(element) { | |
| 2422 this.element = element; | |
| 2423 this.color = window.getComputedStyle(element).color; | |
| 2424 this.wave = document.createElement('div'); | |
| 2425 this.waveContainer = document.createElement('div'); | |
| 2426 this.wave.style.backgroundColor = this.color; | |
| 2427 this.wave.classList.add('wave'); | |
| 2428 this.waveContainer.classList.add('wave-container'); | |
| 2429 Polymer.dom(this.waveContainer).appendChild(this.wave); | |
| 2430 this.resetInteractionState(); | |
| 2431 } | |
| 2432 Ripple.MAX_RADIUS = 300; | |
| 2433 Ripple.prototype = { | |
| 2434 get recenters() { | |
| 2435 return this.element.recenters; | |
| 2436 }, | |
| 2437 get center() { | |
| 2438 return this.element.center; | |
| 2439 }, | |
| 2440 get mouseDownElapsed() { | |
| 2441 var elapsed; | |
| 2442 if (!this.mouseDownStart) { | |
| 2443 return 0; | |
| 2444 } | |
| 2445 elapsed = Utility.now() - this.mouseDownStart; | |
| 2446 if (this.mouseUpStart) { | |
| 2447 elapsed -= this.mouseUpElapsed; | |
| 2448 } | |
| 2449 return elapsed; | |
| 2450 }, | |
| 2451 get mouseUpElapsed() { | |
| 2452 return this.mouseUpStart ? Utility.now() - this.mouseUpStart : 0; | |
| 2453 }, | |
| 2454 get mouseDownElapsedSeconds() { | |
| 2455 return this.mouseDownElapsed / 1e3; | |
| 2456 }, | |
| 2457 get mouseUpElapsedSeconds() { | |
| 2458 return this.mouseUpElapsed / 1e3; | |
| 2459 }, | |
| 2460 get mouseInteractionSeconds() { | |
| 2461 return this.mouseDownElapsedSeconds + this.mouseUpElapsedSeconds; | |
| 2462 }, | |
| 2463 get initialOpacity() { | |
| 2464 return this.element.initialOpacity; | |
| 2465 }, | |
| 2466 get opacityDecayVelocity() { | |
| 2467 return this.element.opacityDecayVelocity; | |
| 2468 }, | |
| 2469 get radius() { | |
| 2470 var width2 = this.containerMetrics.width * this.containerMetrics.width; | |
| 2471 var height2 = this.containerMetrics.height * this.containerMetrics.height; | |
| 2472 var waveRadius = Math.min(Math.sqrt(width2 + height2), Ripple.MAX_RADIUS)
* 1.1 + 5; | |
| 2473 var duration = 1.1 - .2 * (waveRadius / Ripple.MAX_RADIUS); | |
| 2474 var timeNow = this.mouseInteractionSeconds / duration; | |
| 2475 var size = waveRadius * (1 - Math.pow(80, -timeNow)); | |
| 2476 return Math.abs(size); | |
| 2477 }, | |
| 2478 get opacity() { | |
| 2479 if (!this.mouseUpStart) { | |
| 2480 return this.initialOpacity; | |
| 2481 } | |
| 2482 return Math.max(0, this.initialOpacity - this.mouseUpElapsedSeconds * this
.opacityDecayVelocity); | |
| 2483 }, | |
| 2484 get outerOpacity() { | |
| 2485 var outerOpacity = this.mouseUpElapsedSeconds * .3; | |
| 2486 var waveOpacity = this.opacity; | |
| 2487 return Math.max(0, Math.min(outerOpacity, waveOpacity)); | |
| 2488 }, | |
| 2489 get isOpacityFullyDecayed() { | |
| 2490 return this.opacity < .01 && this.radius >= Math.min(this.maxRadius, Rippl
e.MAX_RADIUS); | |
| 2491 }, | |
| 2492 get isRestingAtMaxRadius() { | |
| 2493 return this.opacity >= this.initialOpacity && this.radius >= Math.min(this
.maxRadius, Ripple.MAX_RADIUS); | |
| 2494 }, | |
| 2495 get isAnimationComplete() { | |
| 2496 return this.mouseUpStart ? this.isOpacityFullyDecayed : this.isRestingAtMa
xRadius; | |
| 2497 }, | |
| 2498 get translationFraction() { | |
| 2499 return Math.min(1, this.radius / this.containerMetrics.size * 2 / Math.sqr
t(2)); | |
| 2500 }, | |
| 2501 get xNow() { | |
| 2502 if (this.xEnd) { | |
| 2503 return this.xStart + this.translationFraction * (this.xEnd - this.xStart
); | |
| 2504 } | |
| 2505 return this.xStart; | |
| 2506 }, | |
| 2507 get yNow() { | |
| 2508 if (this.yEnd) { | |
| 2509 return this.yStart + this.translationFraction * (this.yEnd - this.yStart
); | |
| 2510 } | |
| 2511 return this.yStart; | |
| 2512 }, | |
| 2513 get isMouseDown() { | |
| 2514 return this.mouseDownStart && !this.mouseUpStart; | |
| 2515 }, | |
| 2516 resetInteractionState: function() { | |
| 2517 this.maxRadius = 0; | |
| 2518 this.mouseDownStart = 0; | |
| 2519 this.mouseUpStart = 0; | |
| 2520 this.xStart = 0; | |
| 2521 this.yStart = 0; | |
| 2522 this.xEnd = 0; | |
| 2523 this.yEnd = 0; | |
| 2524 this.slideDistance = 0; | |
| 2525 this.containerMetrics = new ElementMetrics(this.element); | |
| 2526 }, | |
| 2527 draw: function() { | |
| 2528 var scale; | |
| 2529 var translateString; | |
| 2530 var dx; | |
| 2531 var dy; | |
| 2532 this.wave.style.opacity = this.opacity; | |
| 2533 scale = this.radius / (this.containerMetrics.size / 2); | |
| 2534 dx = this.xNow - this.containerMetrics.width / 2; | |
| 2535 dy = this.yNow - this.containerMetrics.height / 2; | |
| 2536 this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy
+ 'px)'; | |
| 2537 this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + '
px, 0)'; | |
| 2538 this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')'; | |
| 2539 this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)'; | |
| 2540 }, | |
| 2541 downAction: function(event) { | |
| 2542 var xCenter = this.containerMetrics.width / 2; | |
| 2543 var yCenter = this.containerMetrics.height / 2; | |
| 2544 this.resetInteractionState(); | |
| 2545 this.mouseDownStart = Utility.now(); | |
| 2546 if (this.center) { | |
| 2547 this.xStart = xCenter; | |
| 2548 this.yStart = yCenter; | |
| 2549 this.slideDistance = Utility.distance(this.xStart, this.yStart, this.xEn
d, this.yEnd); | |
| 2550 } else { | |
| 2551 this.xStart = event ? event.detail.x - this.containerMetrics.boundingRec
t.left : this.containerMetrics.width / 2; | |
| 2552 this.yStart = event ? event.detail.y - this.containerMetrics.boundingRec
t.top : this.containerMetrics.height / 2; | |
| 2553 } | |
| 2554 if (this.recenters) { | |
| 2555 this.xEnd = xCenter; | |
| 2556 this.yEnd = yCenter; | |
| 2557 this.slideDistance = Utility.distance(this.xStart, this.yStart, this.xEn
d, this.yEnd); | |
| 2558 } | |
| 2559 this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom(this.xSt
art, this.yStart); | |
| 2560 this.waveContainer.style.top = (this.containerMetrics.height - this.contai
nerMetrics.size) / 2 + 'px'; | |
| 2561 this.waveContainer.style.left = (this.containerMetrics.width - this.contai
nerMetrics.size) / 2 + 'px'; | |
| 2562 this.waveContainer.style.width = this.containerMetrics.size + 'px'; | |
| 2563 this.waveContainer.style.height = this.containerMetrics.size + 'px'; | |
| 2564 }, | |
| 2565 upAction: function(event) { | |
| 2566 if (!this.isMouseDown) { | |
| 2567 return; | |
| 2568 } | |
| 2569 this.mouseUpStart = Utility.now(); | |
| 2570 }, | |
| 2571 remove: function() { | |
| 2572 Polymer.dom(this.waveContainer.parentNode).removeChild(this.waveContainer)
; | |
| 2573 } | |
| 2574 }; | |
| 2575 Polymer({ | 2637 Polymer({ |
| 2576 is: 'paper-ripple', | 2638 is: 'iron-overlay-backdrop', |
| 2577 behaviors: [ Polymer.IronA11yKeysBehavior ], | |
| 2578 properties: { | 2639 properties: { |
| 2579 initialOpacity: { | 2640 opened: { |
| 2580 type: Number, | |
| 2581 value: .25 | |
| 2582 }, | |
| 2583 opacityDecayVelocity: { | |
| 2584 type: Number, | |
| 2585 value: .8 | |
| 2586 }, | |
| 2587 recenters: { | |
| 2588 type: Boolean, | |
| 2589 value: false | |
| 2590 }, | |
| 2591 center: { | |
| 2592 type: Boolean, | |
| 2593 value: false | |
| 2594 }, | |
| 2595 ripples: { | |
| 2596 type: Array, | |
| 2597 value: function() { | |
| 2598 return []; | |
| 2599 } | |
| 2600 }, | |
| 2601 animating: { | |
| 2602 type: Boolean, | |
| 2603 readOnly: true, | |
| 2604 reflectToAttribute: true, | 2641 reflectToAttribute: true, |
| 2605 value: false | |
| 2606 }, | |
| 2607 holdDown: { | |
| 2608 type: Boolean, | 2642 type: Boolean, |
| 2609 value: false, | 2643 value: false, |
| 2610 observer: '_holdDownChanged' | 2644 observer: '_openedChanged' |
| 2611 }, | 2645 } |
| 2612 noink: { | 2646 }, |
| 2613 type: Boolean, | 2647 listeners: { |
| 2614 value: false | 2648 transitionend: '_onTransitionend' |
| 2615 }, | 2649 }, |
| 2616 _animating: { | 2650 created: function() { |
| 2617 type: Boolean | 2651 this.__openedRaf = null; |
| 2618 }, | 2652 }, |
| 2619 _boundAnimate: { | 2653 attached: function() { |
| 2620 type: Function, | 2654 this.opened && this._openedChanged(this.opened); |
| 2621 value: function() { | 2655 }, |
| 2622 return this.animate.bind(this); | 2656 prepare: function() { |
| 2657 if (this.opened && !this.parentNode) { |
| 2658 Polymer.dom(document.body).appendChild(this); |
| 2659 } |
| 2660 }, |
| 2661 open: function() { |
| 2662 this.opened = true; |
| 2663 }, |
| 2664 close: function() { |
| 2665 this.opened = false; |
| 2666 }, |
| 2667 complete: function() { |
| 2668 if (!this.opened && this.parentNode === document.body) { |
| 2669 Polymer.dom(this.parentNode).removeChild(this); |
| 2670 } |
| 2671 }, |
| 2672 _onTransitionend: function(event) { |
| 2673 if (event && event.target === this) { |
| 2674 this.complete(); |
| 2675 } |
| 2676 }, |
| 2677 _openedChanged: function(opened) { |
| 2678 if (opened) { |
| 2679 this.prepare(); |
| 2680 } else { |
| 2681 var cs = window.getComputedStyle(this); |
| 2682 if (cs.transitionDuration === '0s' || cs.opacity == 0) { |
| 2683 this.complete(); |
| 2623 } | 2684 } |
| 2624 } | 2685 } |
| 2625 }, | 2686 if (!this.isAttached) { |
| 2626 get target() { | |
| 2627 return this.keyEventTarget; | |
| 2628 }, | |
| 2629 keyBindings: { | |
| 2630 'enter:keydown': '_onEnterKeydown', | |
| 2631 'space:keydown': '_onSpaceKeydown', | |
| 2632 'space:keyup': '_onSpaceKeyup' | |
| 2633 }, | |
| 2634 attached: function() { | |
| 2635 if (this.parentNode.nodeType == 11) { | |
| 2636 this.keyEventTarget = Polymer.dom(this).getOwnerRoot().host; | |
| 2637 } else { | |
| 2638 this.keyEventTarget = this.parentNode; | |
| 2639 } | |
| 2640 var keyEventTarget = this.keyEventTarget; | |
| 2641 this.listen(keyEventTarget, 'up', 'uiUpAction'); | |
| 2642 this.listen(keyEventTarget, 'down', 'uiDownAction'); | |
| 2643 }, | |
| 2644 detached: function() { | |
| 2645 this.unlisten(this.keyEventTarget, 'up', 'uiUpAction'); | |
| 2646 this.unlisten(this.keyEventTarget, 'down', 'uiDownAction'); | |
| 2647 this.keyEventTarget = null; | |
| 2648 }, | |
| 2649 get shouldKeepAnimating() { | |
| 2650 for (var index = 0; index < this.ripples.length; ++index) { | |
| 2651 if (!this.ripples[index].isAnimationComplete) { | |
| 2652 return true; | |
| 2653 } | |
| 2654 } | |
| 2655 return false; | |
| 2656 }, | |
| 2657 simulatedRipple: function() { | |
| 2658 this.downAction(null); | |
| 2659 this.async(function() { | |
| 2660 this.upAction(); | |
| 2661 }, 1); | |
| 2662 }, | |
| 2663 uiDownAction: function(event) { | |
| 2664 if (!this.noink) { | |
| 2665 this.downAction(event); | |
| 2666 } | |
| 2667 }, | |
| 2668 downAction: function(event) { | |
| 2669 if (this.holdDown && this.ripples.length > 0) { | |
| 2670 return; | 2687 return; |
| 2671 } | 2688 } |
| 2672 var ripple = this.addRipple(); | 2689 if (this.__openedRaf) { |
| 2673 ripple.downAction(event); | 2690 window.cancelAnimationFrame(this.__openedRaf); |
| 2674 if (!this._animating) { | 2691 this.__openedRaf = null; |
| 2675 this._animating = true; | 2692 } |
| 2676 this.animate(); | 2693 this.scrollTop = this.scrollTop; |
| 2677 } | 2694 this.__openedRaf = window.requestAnimationFrame(function() { |
| 2678 }, | 2695 this.__openedRaf = null; |
| 2679 uiUpAction: function(event) { | 2696 this.toggleClass('opened', this.opened); |
| 2680 if (!this.noink) { | 2697 }.bind(this)); |
| 2681 this.upAction(event); | |
| 2682 } | |
| 2683 }, | |
| 2684 upAction: function(event) { | |
| 2685 if (this.holdDown) { | |
| 2686 return; | |
| 2687 } | |
| 2688 this.ripples.forEach(function(ripple) { | |
| 2689 ripple.upAction(event); | |
| 2690 }); | |
| 2691 this._animating = true; | |
| 2692 this.animate(); | |
| 2693 }, | |
| 2694 onAnimationComplete: function() { | |
| 2695 this._animating = false; | |
| 2696 this.$.background.style.backgroundColor = null; | |
| 2697 this.fire('transitionend'); | |
| 2698 }, | |
| 2699 addRipple: function() { | |
| 2700 var ripple = new Ripple(this); | |
| 2701 Polymer.dom(this.$.waves).appendChild(ripple.waveContainer); | |
| 2702 this.$.background.style.backgroundColor = ripple.color; | |
| 2703 this.ripples.push(ripple); | |
| 2704 this._setAnimating(true); | |
| 2705 return ripple; | |
| 2706 }, | |
| 2707 removeRipple: function(ripple) { | |
| 2708 var rippleIndex = this.ripples.indexOf(ripple); | |
| 2709 if (rippleIndex < 0) { | |
| 2710 return; | |
| 2711 } | |
| 2712 this.ripples.splice(rippleIndex, 1); | |
| 2713 ripple.remove(); | |
| 2714 if (!this.ripples.length) { | |
| 2715 this._setAnimating(false); | |
| 2716 } | |
| 2717 }, | |
| 2718 animate: function() { | |
| 2719 if (!this._animating) { | |
| 2720 return; | |
| 2721 } | |
| 2722 var index; | |
| 2723 var ripple; | |
| 2724 for (index = 0; index < this.ripples.length; ++index) { | |
| 2725 ripple = this.ripples[index]; | |
| 2726 ripple.draw(); | |
| 2727 this.$.background.style.opacity = ripple.outerOpacity; | |
| 2728 if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) { | |
| 2729 this.removeRipple(ripple); | |
| 2730 } | |
| 2731 } | |
| 2732 if (!this.shouldKeepAnimating && this.ripples.length === 0) { | |
| 2733 this.onAnimationComplete(); | |
| 2734 } else { | |
| 2735 window.requestAnimationFrame(this._boundAnimate); | |
| 2736 } | |
| 2737 }, | |
| 2738 _onEnterKeydown: function() { | |
| 2739 this.uiDownAction(); | |
| 2740 this.async(this.uiUpAction, 1); | |
| 2741 }, | |
| 2742 _onSpaceKeydown: function() { | |
| 2743 this.uiDownAction(); | |
| 2744 }, | |
| 2745 _onSpaceKeyup: function() { | |
| 2746 this.uiUpAction(); | |
| 2747 }, | |
| 2748 _holdDownChanged: function(newVal, oldVal) { | |
| 2749 if (oldVal === undefined) { | |
| 2750 return; | |
| 2751 } | |
| 2752 if (newVal) { | |
| 2753 this.downAction(); | |
| 2754 } else { | |
| 2755 this.upAction(); | |
| 2756 } | |
| 2757 } | 2698 } |
| 2758 }); | 2699 }); |
| 2759 })(); | 2700 })(); |
| 2760 | 2701 |
| 2761 Polymer.PaperRippleBehavior = { | 2702 Polymer.IronOverlayManagerClass = function() { |
| 2762 properties: { | 2703 this._overlays = []; |
| 2763 noink: { | 2704 this._minimumZ = 101; |
| 2764 type: Boolean, | 2705 this._backdropElement = null; |
| 2765 observer: '_noinkChanged' | 2706 Polymer.Gestures.add(document, 'tap', this._onCaptureClick.bind(this)); |
| 2766 }, | 2707 document.addEventListener('focus', this._onCaptureFocus.bind(this), true); |
| 2767 _rippleContainer: { | 2708 document.addEventListener('keydown', this._onCaptureKeyDown.bind(this), true); |
| 2768 type: Object | 2709 }; |
| 2769 } | 2710 |
| 2770 }, | 2711 Polymer.IronOverlayManagerClass.prototype = { |
| 2771 _buttonStateChanged: function() { | 2712 constructor: Polymer.IronOverlayManagerClass, |
| 2772 if (this.focused) { | 2713 get backdropElement() { |
| 2773 this.ensureRipple(); | 2714 if (!this._backdropElement) { |
| 2774 } | 2715 this._backdropElement = document.createElement('iron-overlay-backdrop'); |
| 2775 }, | 2716 } |
| 2776 _downHandler: function(event) { | 2717 return this._backdropElement; |
| 2777 Polymer.IronButtonStateImpl._downHandler.call(this, event); | 2718 }, |
| 2778 if (this.pressed) { | 2719 get deepActiveElement() { |
| 2779 this.ensureRipple(event); | 2720 var active = document.activeElement || document.body; |
| 2780 } | 2721 while (active.root && Polymer.dom(active.root).activeElement) { |
| 2781 }, | 2722 active = Polymer.dom(active.root).activeElement; |
| 2782 ensureRipple: function(optTriggeringEvent) { | 2723 } |
| 2783 if (!this.hasRipple()) { | 2724 return active; |
| 2784 this._ripple = this._createRipple(); | 2725 }, |
| 2785 this._ripple.noink = this.noink; | 2726 _bringOverlayAtIndexToFront: function(i) { |
| 2786 var rippleContainer = this._rippleContainer || this.root; | 2727 var overlay = this._overlays[i]; |
| 2787 if (rippleContainer) { | 2728 if (!overlay) { |
| 2788 Polymer.dom(rippleContainer).appendChild(this._ripple); | 2729 return; |
| 2789 } | 2730 } |
| 2790 if (optTriggeringEvent) { | 2731 var lastI = this._overlays.length - 1; |
| 2791 var domContainer = Polymer.dom(this._rippleContainer || this); | 2732 var currentOverlay = this._overlays[lastI]; |
| 2792 var target = Polymer.dom(optTriggeringEvent).rootTarget; | 2733 if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay))
{ |
| 2793 if (domContainer.deepContains(target)) { | 2734 lastI--; |
| 2794 this._ripple.uiDownAction(optTriggeringEvent); | 2735 } |
| 2795 } | 2736 if (i >= lastI) { |
| 2796 } | 2737 return; |
| 2797 } | 2738 } |
| 2798 }, | 2739 var minimumZ = Math.max(this.currentOverlayZ(), this._minimumZ); |
| 2799 getRipple: function() { | 2740 if (this._getZ(overlay) <= minimumZ) { |
| 2800 this.ensureRipple(); | 2741 this._applyOverlayZ(overlay, minimumZ); |
| 2801 return this._ripple; | 2742 } |
| 2802 }, | 2743 while (i < lastI) { |
| 2803 hasRipple: function() { | 2744 this._overlays[i] = this._overlays[i + 1]; |
| 2804 return Boolean(this._ripple); | 2745 i++; |
| 2805 }, | 2746 } |
| 2806 _createRipple: function() { | 2747 this._overlays[lastI] = overlay; |
| 2807 return document.createElement('paper-ripple'); | 2748 }, |
| 2808 }, | 2749 addOrRemoveOverlay: function(overlay) { |
| 2809 _noinkChanged: function(noink) { | 2750 if (overlay.opened) { |
| 2810 if (this.hasRipple()) { | 2751 this.addOverlay(overlay); |
| 2811 this._ripple.noink = noink; | 2752 } else { |
| 2812 } | 2753 this.removeOverlay(overlay); |
| 2754 } |
| 2755 }, |
| 2756 addOverlay: function(overlay) { |
| 2757 var i = this._overlays.indexOf(overlay); |
| 2758 if (i >= 0) { |
| 2759 this._bringOverlayAtIndexToFront(i); |
| 2760 this.trackBackdrop(); |
| 2761 return; |
| 2762 } |
| 2763 var insertionIndex = this._overlays.length; |
| 2764 var currentOverlay = this._overlays[insertionIndex - 1]; |
| 2765 var minimumZ = Math.max(this._getZ(currentOverlay), this._minimumZ); |
| 2766 var newZ = this._getZ(overlay); |
| 2767 if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay))
{ |
| 2768 this._applyOverlayZ(currentOverlay, minimumZ); |
| 2769 insertionIndex--; |
| 2770 var previousOverlay = this._overlays[insertionIndex - 1]; |
| 2771 minimumZ = Math.max(this._getZ(previousOverlay), this._minimumZ); |
| 2772 } |
| 2773 if (newZ <= minimumZ) { |
| 2774 this._applyOverlayZ(overlay, minimumZ); |
| 2775 } |
| 2776 this._overlays.splice(insertionIndex, 0, overlay); |
| 2777 this.trackBackdrop(); |
| 2778 }, |
| 2779 removeOverlay: function(overlay) { |
| 2780 var i = this._overlays.indexOf(overlay); |
| 2781 if (i === -1) { |
| 2782 return; |
| 2783 } |
| 2784 this._overlays.splice(i, 1); |
| 2785 this.trackBackdrop(); |
| 2786 }, |
| 2787 currentOverlay: function() { |
| 2788 var i = this._overlays.length - 1; |
| 2789 return this._overlays[i]; |
| 2790 }, |
| 2791 currentOverlayZ: function() { |
| 2792 return this._getZ(this.currentOverlay()); |
| 2793 }, |
| 2794 ensureMinimumZ: function(minimumZ) { |
| 2795 this._minimumZ = Math.max(this._minimumZ, minimumZ); |
| 2796 }, |
| 2797 focusOverlay: function() { |
| 2798 var current = this.currentOverlay(); |
| 2799 if (current) { |
| 2800 current._applyFocus(); |
| 2801 } |
| 2802 }, |
| 2803 trackBackdrop: function() { |
| 2804 var overlay = this._overlayWithBackdrop(); |
| 2805 if (!overlay && !this._backdropElement) { |
| 2806 return; |
| 2807 } |
| 2808 this.backdropElement.style.zIndex = this._getZ(overlay) - 1; |
| 2809 this.backdropElement.opened = !!overlay; |
| 2810 }, |
| 2811 getBackdrops: function() { |
| 2812 var backdrops = []; |
| 2813 for (var i = 0; i < this._overlays.length; i++) { |
| 2814 if (this._overlays[i].withBackdrop) { |
| 2815 backdrops.push(this._overlays[i]); |
| 2816 } |
| 2817 } |
| 2818 return backdrops; |
| 2819 }, |
| 2820 backdropZ: function() { |
| 2821 return this._getZ(this._overlayWithBackdrop()) - 1; |
| 2822 }, |
| 2823 _overlayWithBackdrop: function() { |
| 2824 for (var i = 0; i < this._overlays.length; i++) { |
| 2825 if (this._overlays[i].withBackdrop) { |
| 2826 return this._overlays[i]; |
| 2827 } |
| 2828 } |
| 2829 }, |
| 2830 _getZ: function(overlay) { |
| 2831 var z = this._minimumZ; |
| 2832 if (overlay) { |
| 2833 var z1 = Number(overlay.style.zIndex || window.getComputedStyle(overlay).z
Index); |
| 2834 if (z1 === z1) { |
| 2835 z = z1; |
| 2836 } |
| 2837 } |
| 2838 return z; |
| 2839 }, |
| 2840 _setZ: function(element, z) { |
| 2841 element.style.zIndex = z; |
| 2842 }, |
| 2843 _applyOverlayZ: function(overlay, aboveZ) { |
| 2844 this._setZ(overlay, aboveZ + 2); |
| 2845 }, |
| 2846 _overlayInPath: function(path) { |
| 2847 path = path || []; |
| 2848 for (var i = 0; i < path.length; i++) { |
| 2849 if (path[i]._manager === this) { |
| 2850 return path[i]; |
| 2851 } |
| 2852 } |
| 2853 }, |
| 2854 _onCaptureClick: function(event) { |
| 2855 var overlay = this.currentOverlay(); |
| 2856 if (overlay && this._overlayInPath(Polymer.dom(event).path) !== overlay) { |
| 2857 overlay._onCaptureClick(event); |
| 2858 } |
| 2859 }, |
| 2860 _onCaptureFocus: function(event) { |
| 2861 var overlay = this.currentOverlay(); |
| 2862 if (overlay) { |
| 2863 overlay._onCaptureFocus(event); |
| 2864 } |
| 2865 }, |
| 2866 _onCaptureKeyDown: function(event) { |
| 2867 var overlay = this.currentOverlay(); |
| 2868 if (overlay) { |
| 2869 if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(event, 'esc')) { |
| 2870 overlay._onCaptureEsc(event); |
| 2871 } else if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(event, 't
ab')) { |
| 2872 overlay._onCaptureTab(event); |
| 2873 } |
| 2874 } |
| 2875 }, |
| 2876 _shouldBeBehindOverlay: function(overlay1, overlay2) { |
| 2877 return !overlay1.alwaysOnTop && overlay2.alwaysOnTop; |
| 2813 } | 2878 } |
| 2814 }; | 2879 }; |
| 2815 | 2880 |
| 2816 Polymer.PaperButtonBehaviorImpl = { | 2881 Polymer.IronOverlayManager = new Polymer.IronOverlayManagerClass(); |
| 2817 properties: { | |
| 2818 elevation: { | |
| 2819 type: Number, | |
| 2820 reflectToAttribute: true, | |
| 2821 readOnly: true | |
| 2822 } | |
| 2823 }, | |
| 2824 observers: [ '_calculateElevation(focused, disabled, active, pressed, received
FocusFromKeyboard)', '_computeKeyboardClass(receivedFocusFromKeyboard)' ], | |
| 2825 hostAttributes: { | |
| 2826 role: 'button', | |
| 2827 tabindex: '0', | |
| 2828 animated: true | |
| 2829 }, | |
| 2830 _calculateElevation: function() { | |
| 2831 var e = 1; | |
| 2832 if (this.disabled) { | |
| 2833 e = 0; | |
| 2834 } else if (this.active || this.pressed) { | |
| 2835 e = 4; | |
| 2836 } else if (this.receivedFocusFromKeyboard) { | |
| 2837 e = 3; | |
| 2838 } | |
| 2839 this._setElevation(e); | |
| 2840 }, | |
| 2841 _computeKeyboardClass: function(receivedFocusFromKeyboard) { | |
| 2842 this.toggleClass('keyboard-focus', receivedFocusFromKeyboard); | |
| 2843 }, | |
| 2844 _spaceKeyDownHandler: function(event) { | |
| 2845 Polymer.IronButtonStateImpl._spaceKeyDownHandler.call(this, event); | |
| 2846 if (this.hasRipple() && this.getRipple().ripples.length < 1) { | |
| 2847 this._ripple.uiDownAction(); | |
| 2848 } | |
| 2849 }, | |
| 2850 _spaceKeyUpHandler: function(event) { | |
| 2851 Polymer.IronButtonStateImpl._spaceKeyUpHandler.call(this, event); | |
| 2852 if (this.hasRipple()) { | |
| 2853 this._ripple.uiUpAction(); | |
| 2854 } | |
| 2855 } | |
| 2856 }; | |
| 2857 | 2882 |
| 2858 Polymer.PaperButtonBehavior = [ Polymer.IronButtonState, Polymer.IronControlStat
e, Polymer.PaperRippleBehavior, Polymer.PaperButtonBehaviorImpl ]; | 2883 (function() { |
| 2859 | 2884 'use strict'; |
| 2860 Polymer({ | 2885 Polymer.IronOverlayBehaviorImpl = { |
| 2861 is: 'paper-button', | 2886 properties: { |
| 2862 behaviors: [ Polymer.PaperButtonBehavior ], | 2887 opened: { |
| 2863 properties: { | 2888 observer: '_openedChanged', |
| 2864 raised: { | 2889 type: Boolean, |
| 2865 type: Boolean, | 2890 value: false, |
| 2866 reflectToAttribute: true, | 2891 notify: true |
| 2867 value: false, | 2892 }, |
| 2868 observer: '_calculateElevation' | 2893 canceled: { |
| 2869 } | 2894 observer: '_canceledChanged', |
| 2870 }, | 2895 readOnly: true, |
| 2871 _calculateElevation: function() { | 2896 type: Boolean, |
| 2872 if (!this.raised) { | 2897 value: false |
| 2873 this._setElevation(0); | 2898 }, |
| 2874 } else { | 2899 withBackdrop: { |
| 2875 Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this); | 2900 observer: '_withBackdropChanged', |
| 2876 } | 2901 type: Boolean |
| 2877 } | 2902 }, |
| 2878 }); | 2903 noAutoFocus: { |
| 2904 type: Boolean, |
| 2905 value: false |
| 2906 }, |
| 2907 noCancelOnEscKey: { |
| 2908 type: Boolean, |
| 2909 value: false |
| 2910 }, |
| 2911 noCancelOnOutsideClick: { |
| 2912 type: Boolean, |
| 2913 value: false |
| 2914 }, |
| 2915 closingReason: { |
| 2916 type: Object |
| 2917 }, |
| 2918 restoreFocusOnClose: { |
| 2919 type: Boolean, |
| 2920 value: false |
| 2921 }, |
| 2922 alwaysOnTop: { |
| 2923 type: Boolean |
| 2924 }, |
| 2925 _manager: { |
| 2926 type: Object, |
| 2927 value: Polymer.IronOverlayManager |
| 2928 }, |
| 2929 _focusedChild: { |
| 2930 type: Object |
| 2931 } |
| 2932 }, |
| 2933 listeners: { |
| 2934 'iron-resize': '_onIronResize' |
| 2935 }, |
| 2936 get backdropElement() { |
| 2937 return this._manager.backdropElement; |
| 2938 }, |
| 2939 get _focusNode() { |
| 2940 return this._focusedChild || Polymer.dom(this).querySelector('[autofocus]'
) || this; |
| 2941 }, |
| 2942 get _focusableNodes() { |
| 2943 var FOCUSABLE_WITH_DISABLED = [ 'a[href]', 'area[href]', 'iframe', '[tabin
dex]', '[contentEditable=true]' ]; |
| 2944 var FOCUSABLE_WITHOUT_DISABLED = [ 'input', 'select', 'textarea', 'button'
]; |
| 2945 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"])'; |
| 2946 var focusables = Polymer.dom(this).querySelectorAll(selector); |
| 2947 if (this.tabIndex >= 0) { |
| 2948 focusables.splice(0, 0, this); |
| 2949 } |
| 2950 return focusables.sort(function(a, b) { |
| 2951 if (a.tabIndex === b.tabIndex) { |
| 2952 return 0; |
| 2953 } |
| 2954 if (a.tabIndex === 0 || a.tabIndex > b.tabIndex) { |
| 2955 return 1; |
| 2956 } |
| 2957 return -1; |
| 2958 }); |
| 2959 }, |
| 2960 ready: function() { |
| 2961 this.__isAnimating = false; |
| 2962 this.__shouldRemoveTabIndex = false; |
| 2963 this.__firstFocusableNode = this.__lastFocusableNode = null; |
| 2964 this.__raf = null; |
| 2965 this.__restoreFocusNode = null; |
| 2966 this._ensureSetup(); |
| 2967 }, |
| 2968 attached: function() { |
| 2969 if (this.opened) { |
| 2970 this._openedChanged(this.opened); |
| 2971 } |
| 2972 this._observer = Polymer.dom(this).observeNodes(this._onNodesChange); |
| 2973 }, |
| 2974 detached: function() { |
| 2975 Polymer.dom(this).unobserveNodes(this._observer); |
| 2976 this._observer = null; |
| 2977 if (this.__raf) { |
| 2978 window.cancelAnimationFrame(this.__raf); |
| 2979 this.__raf = null; |
| 2980 } |
| 2981 this._manager.removeOverlay(this); |
| 2982 }, |
| 2983 toggle: function() { |
| 2984 this._setCanceled(false); |
| 2985 this.opened = !this.opened; |
| 2986 }, |
| 2987 open: function() { |
| 2988 this._setCanceled(false); |
| 2989 this.opened = true; |
| 2990 }, |
| 2991 close: function() { |
| 2992 this._setCanceled(false); |
| 2993 this.opened = false; |
| 2994 }, |
| 2995 cancel: function(event) { |
| 2996 var cancelEvent = this.fire('iron-overlay-canceled', event, { |
| 2997 cancelable: true |
| 2998 }); |
| 2999 if (cancelEvent.defaultPrevented) { |
| 3000 return; |
| 3001 } |
| 3002 this._setCanceled(true); |
| 3003 this.opened = false; |
| 3004 }, |
| 3005 _ensureSetup: function() { |
| 3006 if (this._overlaySetup) { |
| 3007 return; |
| 3008 } |
| 3009 this._overlaySetup = true; |
| 3010 this.style.outline = 'none'; |
| 3011 this.style.display = 'none'; |
| 3012 }, |
| 3013 _openedChanged: function(opened) { |
| 3014 if (opened) { |
| 3015 this.removeAttribute('aria-hidden'); |
| 3016 } else { |
| 3017 this.setAttribute('aria-hidden', 'true'); |
| 3018 } |
| 3019 if (!this.isAttached) { |
| 3020 return; |
| 3021 } |
| 3022 this.__isAnimating = true; |
| 3023 this.__onNextAnimationFrame(this.__openedChanged); |
| 3024 }, |
| 3025 _canceledChanged: function() { |
| 3026 this.closingReason = this.closingReason || {}; |
| 3027 this.closingReason.canceled = this.canceled; |
| 3028 }, |
| 3029 _withBackdropChanged: function() { |
| 3030 if (this.withBackdrop && !this.hasAttribute('tabindex')) { |
| 3031 this.setAttribute('tabindex', '-1'); |
| 3032 this.__shouldRemoveTabIndex = true; |
| 3033 } else if (this.__shouldRemoveTabIndex) { |
| 3034 this.removeAttribute('tabindex'); |
| 3035 this.__shouldRemoveTabIndex = false; |
| 3036 } |
| 3037 if (this.opened && this.isAttached) { |
| 3038 this._manager.trackBackdrop(); |
| 3039 } |
| 3040 }, |
| 3041 _prepareRenderOpened: function() { |
| 3042 this.__restoreFocusNode = this._manager.deepActiveElement; |
| 3043 this._preparePositioning(); |
| 3044 this.refit(); |
| 3045 this._finishPositioning(); |
| 3046 if (this.noAutoFocus && document.activeElement === this._focusNode) { |
| 3047 this._focusNode.blur(); |
| 3048 this.__restoreFocusNode.focus(); |
| 3049 } |
| 3050 }, |
| 3051 _renderOpened: function() { |
| 3052 this._finishRenderOpened(); |
| 3053 }, |
| 3054 _renderClosed: function() { |
| 3055 this._finishRenderClosed(); |
| 3056 }, |
| 3057 _finishRenderOpened: function() { |
| 3058 this.notifyResize(); |
| 3059 this.__isAnimating = false; |
| 3060 var focusableNodes = this._focusableNodes; |
| 3061 this.__firstFocusableNode = focusableNodes[0]; |
| 3062 this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1]; |
| 3063 this.fire('iron-overlay-opened'); |
| 3064 }, |
| 3065 _finishRenderClosed: function() { |
| 3066 this.style.display = 'none'; |
| 3067 this.style.zIndex = ''; |
| 3068 this.notifyResize(); |
| 3069 this.__isAnimating = false; |
| 3070 this.fire('iron-overlay-closed', this.closingReason); |
| 3071 }, |
| 3072 _preparePositioning: function() { |
| 3073 this.style.transition = this.style.webkitTransition = 'none'; |
| 3074 this.style.transform = this.style.webkitTransform = 'none'; |
| 3075 this.style.display = ''; |
| 3076 }, |
| 3077 _finishPositioning: function() { |
| 3078 this.style.display = 'none'; |
| 3079 this.scrollTop = this.scrollTop; |
| 3080 this.style.transition = this.style.webkitTransition = ''; |
| 3081 this.style.transform = this.style.webkitTransform = ''; |
| 3082 this.style.display = ''; |
| 3083 this.scrollTop = this.scrollTop; |
| 3084 }, |
| 3085 _applyFocus: function() { |
| 3086 if (this.opened) { |
| 3087 if (!this.noAutoFocus) { |
| 3088 this._focusNode.focus(); |
| 3089 } |
| 3090 } else { |
| 3091 this._focusNode.blur(); |
| 3092 this._focusedChild = null; |
| 3093 if (this.restoreFocusOnClose && this.__restoreFocusNode) { |
| 3094 this.__restoreFocusNode.focus(); |
| 3095 } |
| 3096 this.__restoreFocusNode = null; |
| 3097 var currentOverlay = this._manager.currentOverlay(); |
| 3098 if (currentOverlay && this !== currentOverlay) { |
| 3099 currentOverlay._applyFocus(); |
| 3100 } |
| 3101 } |
| 3102 }, |
| 3103 _onCaptureClick: function(event) { |
| 3104 if (!this.noCancelOnOutsideClick) { |
| 3105 this.cancel(event); |
| 3106 } |
| 3107 }, |
| 3108 _onCaptureFocus: function(event) { |
| 3109 if (!this.withBackdrop) { |
| 3110 return; |
| 3111 } |
| 3112 var path = Polymer.dom(event).path; |
| 3113 if (path.indexOf(this) === -1) { |
| 3114 event.stopPropagation(); |
| 3115 this._applyFocus(); |
| 3116 } else { |
| 3117 this._focusedChild = path[0]; |
| 3118 } |
| 3119 }, |
| 3120 _onCaptureEsc: function(event) { |
| 3121 if (!this.noCancelOnEscKey) { |
| 3122 this.cancel(event); |
| 3123 } |
| 3124 }, |
| 3125 _onCaptureTab: function(event) { |
| 3126 if (!this.withBackdrop) { |
| 3127 return; |
| 3128 } |
| 3129 var shift = event.shiftKey; |
| 3130 var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusable
Node; |
| 3131 var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNo
de; |
| 3132 var shouldWrap = false; |
| 3133 if (nodeToCheck === nodeToSet) { |
| 3134 shouldWrap = true; |
| 3135 } else { |
| 3136 var focusedNode = this._manager.deepActiveElement; |
| 3137 shouldWrap = focusedNode === nodeToCheck || focusedNode === this; |
| 3138 } |
| 3139 if (shouldWrap) { |
| 3140 event.preventDefault(); |
| 3141 this._focusedChild = nodeToSet; |
| 3142 this._applyFocus(); |
| 3143 } |
| 3144 }, |
| 3145 _onIronResize: function() { |
| 3146 if (this.opened && !this.__isAnimating) { |
| 3147 this.__onNextAnimationFrame(this.refit); |
| 3148 } |
| 3149 }, |
| 3150 _onNodesChange: function() { |
| 3151 if (this.opened && !this.__isAnimating) { |
| 3152 this.notifyResize(); |
| 3153 } |
| 3154 }, |
| 3155 __openedChanged: function() { |
| 3156 if (this.opened) { |
| 3157 this._prepareRenderOpened(); |
| 3158 this._manager.addOverlay(this); |
| 3159 this._applyFocus(); |
| 3160 this._renderOpened(); |
| 3161 } else { |
| 3162 this._manager.removeOverlay(this); |
| 3163 this._applyFocus(); |
| 3164 this._renderClosed(); |
| 3165 } |
| 3166 }, |
| 3167 __onNextAnimationFrame: function(callback) { |
| 3168 if (this.__raf) { |
| 3169 window.cancelAnimationFrame(this.__raf); |
| 3170 } |
| 3171 var self = this; |
| 3172 this.__raf = window.requestAnimationFrame(function nextAnimationFrame() { |
| 3173 self.__raf = null; |
| 3174 callback.call(self); |
| 3175 }); |
| 3176 } |
| 3177 }; |
| 3178 Polymer.IronOverlayBehavior = [ Polymer.IronFitBehavior, Polymer.IronResizable
Behavior, Polymer.IronOverlayBehaviorImpl ]; |
| 3179 })(); |
| 2879 | 3180 |
| 2880 (function() { | 3181 (function() { |
| 2881 var metaDatas = {}; | 3182 var metaDatas = {}; |
| 2882 var metaArrays = {}; | 3183 var metaArrays = {}; |
| 2883 var singleton = null; | 3184 var singleton = null; |
| 2884 Polymer.IronMeta = Polymer({ | 3185 Polymer.IronMeta = Polymer({ |
| 2885 is: 'iron-meta', | 3186 is: 'iron-meta', |
| 2886 properties: { | 3187 properties: { |
| 2887 type: { | 3188 type: { |
| 2888 type: String, | 3189 type: String, |
| 2889 value: 'default', | 3190 value: 'default', |
| 2890 observer: '_typeChanged' | 3191 observer: '_typeChanged' |
| 2891 }, | 3192 }, |
| 2892 key: { | 3193 key: { |
| 2893 type: String, | 3194 type: String, |
| 2894 observer: '_keyChanged' | |
| 2895 }, | |
| 2896 value: { | |
| 2897 type: Object, | |
| 2898 notify: true, | |
| 2899 observer: '_valueChanged' | |
| 2900 }, | |
| 2901 self: { | |
| 2902 type: Boolean, | |
| 2903 observer: '_selfChanged' | |
| 2904 }, | |
| 2905 list: { | |
| 2906 type: Array, | |
| 2907 notify: true | |
| 2908 } | |
| 2909 }, | |
| 2910 hostAttributes: { | |
| 2911 hidden: true | |
| 2912 }, | |
| 2913 factoryImpl: function(config) { | |
| 2914 if (config) { | |
| 2915 for (var n in config) { | |
| 2916 switch (n) { | |
| 2917 case 'type': | |
| 2918 case 'key': | |
| 2919 case 'value': | |
| 2920 this[n] = config[n]; | |
| 2921 break; | |
| 2922 } | |
| 2923 } | |
| 2924 } | |
| 2925 }, | |
| 2926 created: function() { | |
| 2927 this._metaDatas = metaDatas; | |
| 2928 this._metaArrays = metaArrays; | |
| 2929 }, | |
| 2930 _keyChanged: function(key, old) { | |
| 2931 this._resetRegistration(old); | |
| 2932 }, | |
| 2933 _valueChanged: function(value) { | |
| 2934 this._resetRegistration(this.key); | |
| 2935 }, | |
| 2936 _selfChanged: function(self) { | |
| 2937 if (self) { | |
| 2938 this.value = this; | |
| 2939 } | |
| 2940 }, | |
| 2941 _typeChanged: function(type) { | |
| 2942 this._unregisterKey(this.key); | |
| 2943 if (!metaDatas[type]) { | |
| 2944 metaDatas[type] = {}; | |
| 2945 } | |
| 2946 this._metaData = metaDatas[type]; | |
| 2947 if (!metaArrays[type]) { | |
| 2948 metaArrays[type] = []; | |
| 2949 } | |
| 2950 this.list = metaArrays[type]; | |
| 2951 this._registerKeyValue(this.key, this.value); | |
| 2952 }, | |
| 2953 byKey: function(key) { | |
| 2954 return this._metaData && this._metaData[key]; | |
| 2955 }, | |
| 2956 _resetRegistration: function(oldKey) { | |
| 2957 this._unregisterKey(oldKey); | |
| 2958 this._registerKeyValue(this.key, this.value); | |
| 2959 }, | |
| 2960 _unregisterKey: function(key) { | |
| 2961 this._unregister(key, this._metaData, this.list); | |
| 2962 }, | |
| 2963 _registerKeyValue: function(key, value) { | |
| 2964 this._register(key, value, this._metaData, this.list); | |
| 2965 }, | |
| 2966 _register: function(key, value, data, list) { | |
| 2967 if (key && data && value !== undefined) { | |
| 2968 data[key] = value; | |
| 2969 list.push(value); | |
| 2970 } | |
| 2971 }, | |
| 2972 _unregister: function(key, data, list) { | |
| 2973 if (key && data) { | |
| 2974 if (key in data) { | |
| 2975 var value = data[key]; | |
| 2976 delete data[key]; | |
| 2977 this.arrayDelete(list, value); | |
| 2978 } | |
| 2979 } | |
| 2980 } | |
| 2981 }); | |
| 2982 Polymer.IronMeta.getIronMeta = function getIronMeta() { | |
| 2983 if (singleton === null) { | |
| 2984 singleton = new Polymer.IronMeta(); | |
| 2985 } | |
| 2986 return singleton; | |
| 2987 }; | |
| 2988 Polymer.IronMetaQuery = Polymer({ | |
| 2989 is: 'iron-meta-query', | |
| 2990 properties: { | |
| 2991 type: { | |
| 2992 type: String, | |
| 2993 value: 'default', | |
| 2994 observer: '_typeChanged' | |
| 2995 }, | |
| 2996 key: { | |
| 2997 type: String, | |
| 2998 observer: '_keyChanged' | 3195 observer: '_keyChanged' |
| 2999 }, | 3196 }, |
| 3000 value: { | 3197 value: { |
| 3001 type: Object, | 3198 type: Object, |
| 3002 notify: true, | 3199 notify: true, |
| 3003 readOnly: true | 3200 observer: '_valueChanged' |
| 3201 }, |
| 3202 self: { |
| 3203 type: Boolean, |
| 3204 observer: '_selfChanged' |
| 3004 }, | 3205 }, |
| 3005 list: { | 3206 list: { |
| 3006 type: Array, | 3207 type: Array, |
| 3007 notify: true | 3208 notify: true |
| 3008 } | 3209 } |
| 3009 }, | 3210 }, |
| 3211 hostAttributes: { |
| 3212 hidden: true |
| 3213 }, |
| 3010 factoryImpl: function(config) { | 3214 factoryImpl: function(config) { |
| 3011 if (config) { | 3215 if (config) { |
| 3012 for (var n in config) { | 3216 for (var n in config) { |
| 3013 switch (n) { | 3217 switch (n) { |
| 3014 case 'type': | 3218 case 'type': |
| 3015 case 'key': | 3219 case 'key': |
| 3220 case 'value': |
| 3016 this[n] = config[n]; | 3221 this[n] = config[n]; |
| 3017 break; | 3222 break; |
| 3018 } | 3223 } |
| 3019 } | 3224 } |
| 3020 } | 3225 } |
| 3021 }, | 3226 }, |
| 3022 created: function() { | 3227 created: function() { |
| 3023 this._metaDatas = metaDatas; | 3228 this._metaDatas = metaDatas; |
| 3024 this._metaArrays = metaArrays; | 3229 this._metaArrays = metaArrays; |
| 3025 }, | 3230 }, |
| 3231 _keyChanged: function(key, old) { |
| 3232 this._resetRegistration(old); |
| 3233 }, |
| 3234 _valueChanged: function(value) { |
| 3235 this._resetRegistration(this.key); |
| 3236 }, |
| 3237 _selfChanged: function(self) { |
| 3238 if (self) { |
| 3239 this.value = this; |
| 3240 } |
| 3241 }, |
| 3242 _typeChanged: function(type) { |
| 3243 this._unregisterKey(this.key); |
| 3244 if (!metaDatas[type]) { |
| 3245 metaDatas[type] = {}; |
| 3246 } |
| 3247 this._metaData = metaDatas[type]; |
| 3248 if (!metaArrays[type]) { |
| 3249 metaArrays[type] = []; |
| 3250 } |
| 3251 this.list = metaArrays[type]; |
| 3252 this._registerKeyValue(this.key, this.value); |
| 3253 }, |
| 3254 byKey: function(key) { |
| 3255 return this._metaData && this._metaData[key]; |
| 3256 }, |
| 3257 _resetRegistration: function(oldKey) { |
| 3258 this._unregisterKey(oldKey); |
| 3259 this._registerKeyValue(this.key, this.value); |
| 3260 }, |
| 3261 _unregisterKey: function(key) { |
| 3262 this._unregister(key, this._metaData, this.list); |
| 3263 }, |
| 3264 _registerKeyValue: function(key, value) { |
| 3265 this._register(key, value, this._metaData, this.list); |
| 3266 }, |
| 3267 _register: function(key, value, data, list) { |
| 3268 if (key && data && value !== undefined) { |
| 3269 data[key] = value; |
| 3270 list.push(value); |
| 3271 } |
| 3272 }, |
| 3273 _unregister: function(key, data, list) { |
| 3274 if (key && data) { |
| 3275 if (key in data) { |
| 3276 var value = data[key]; |
| 3277 delete data[key]; |
| 3278 this.arrayDelete(list, value); |
| 3279 } |
| 3280 } |
| 3281 } |
| 3282 }); |
| 3283 Polymer.IronMeta.getIronMeta = function getIronMeta() { |
| 3284 if (singleton === null) { |
| 3285 singleton = new Polymer.IronMeta(); |
| 3286 } |
| 3287 return singleton; |
| 3288 }; |
| 3289 Polymer.IronMetaQuery = Polymer({ |
| 3290 is: 'iron-meta-query', |
| 3291 properties: { |
| 3292 type: { |
| 3293 type: String, |
| 3294 value: 'default', |
| 3295 observer: '_typeChanged' |
| 3296 }, |
| 3297 key: { |
| 3298 type: String, |
| 3299 observer: '_keyChanged' |
| 3300 }, |
| 3301 value: { |
| 3302 type: Object, |
| 3303 notify: true, |
| 3304 readOnly: true |
| 3305 }, |
| 3306 list: { |
| 3307 type: Array, |
| 3308 notify: true |
| 3309 } |
| 3310 }, |
| 3311 factoryImpl: function(config) { |
| 3312 if (config) { |
| 3313 for (var n in config) { |
| 3314 switch (n) { |
| 3315 case 'type': |
| 3316 case 'key': |
| 3317 this[n] = config[n]; |
| 3318 break; |
| 3319 } |
| 3320 } |
| 3321 } |
| 3322 }, |
| 3323 created: function() { |
| 3324 this._metaDatas = metaDatas; |
| 3325 this._metaArrays = metaArrays; |
| 3326 }, |
| 3026 _keyChanged: function(key) { | 3327 _keyChanged: function(key) { |
| 3027 this._setValue(this._metaData && this._metaData[key]); | 3328 this._setValue(this._metaData && this._metaData[key]); |
| 3028 }, | 3329 }, |
| 3029 _typeChanged: function(type) { | 3330 _typeChanged: function(type) { |
| 3030 this._metaData = metaDatas[type]; | 3331 this._metaData = metaDatas[type]; |
| 3031 this.list = metaArrays[type]; | 3332 this.list = metaArrays[type]; |
| 3032 if (this.key) { | 3333 if (this.key) { |
| 3033 this._keyChanged(this.key); | 3334 this._keyChanged(this.key); |
| 3034 } | 3335 } |
| 3035 }, | 3336 }, |
| 3036 byKey: function(key) { | 3337 byKey: function(key) { |
| 3037 return this._metaData && this._metaData[key]; | 3338 return this._metaData && this._metaData[key]; |
| 3038 } | 3339 } |
| 3039 }); | 3340 }); |
| 3040 })(); | 3341 })(); |
| 3041 | 3342 |
| 3042 Polymer({ | |
| 3043 is: 'iron-icon', | |
| 3044 properties: { | |
| 3045 icon: { | |
| 3046 type: String, | |
| 3047 observer: '_iconChanged' | |
| 3048 }, | |
| 3049 theme: { | |
| 3050 type: String, | |
| 3051 observer: '_updateIcon' | |
| 3052 }, | |
| 3053 src: { | |
| 3054 type: String, | |
| 3055 observer: '_srcChanged' | |
| 3056 }, | |
| 3057 _meta: { | |
| 3058 value: Polymer.Base.create('iron-meta', { | |
| 3059 type: 'iconset' | |
| 3060 }), | |
| 3061 observer: '_updateIcon' | |
| 3062 } | |
| 3063 }, | |
| 3064 _DEFAULT_ICONSET: 'icons', | |
| 3065 _iconChanged: function(icon) { | |
| 3066 var parts = (icon || '').split(':'); | |
| 3067 this._iconName = parts.pop(); | |
| 3068 this._iconsetName = parts.pop() || this._DEFAULT_ICONSET; | |
| 3069 this._updateIcon(); | |
| 3070 }, | |
| 3071 _srcChanged: function(src) { | |
| 3072 this._updateIcon(); | |
| 3073 }, | |
| 3074 _usesIconset: function() { | |
| 3075 return this.icon || !this.src; | |
| 3076 }, | |
| 3077 _updateIcon: function() { | |
| 3078 if (this._usesIconset()) { | |
| 3079 if (this._img && this._img.parentNode) { | |
| 3080 Polymer.dom(this.root).removeChild(this._img); | |
| 3081 } | |
| 3082 if (this._iconName === "") { | |
| 3083 if (this._iconset) { | |
| 3084 this._iconset.removeIcon(this); | |
| 3085 } | |
| 3086 } else if (this._iconsetName && this._meta) { | |
| 3087 this._iconset = this._meta.byKey(this._iconsetName); | |
| 3088 if (this._iconset) { | |
| 3089 this._iconset.applyIcon(this, this._iconName, this.theme); | |
| 3090 this.unlisten(window, 'iron-iconset-added', '_updateIcon'); | |
| 3091 } else { | |
| 3092 this.listen(window, 'iron-iconset-added', '_updateIcon'); | |
| 3093 } | |
| 3094 } | |
| 3095 } else { | |
| 3096 if (this._iconset) { | |
| 3097 this._iconset.removeIcon(this); | |
| 3098 } | |
| 3099 if (!this._img) { | |
| 3100 this._img = document.createElement('img'); | |
| 3101 this._img.style.width = '100%'; | |
| 3102 this._img.style.height = '100%'; | |
| 3103 this._img.draggable = false; | |
| 3104 } | |
| 3105 this._img.src = this.src; | |
| 3106 Polymer.dom(this.root).appendChild(this._img); | |
| 3107 } | |
| 3108 } | |
| 3109 }); | |
| 3110 | |
| 3111 Polymer.PaperInkyFocusBehaviorImpl = { | |
| 3112 observers: [ '_focusedChanged(receivedFocusFromKeyboard)' ], | |
| 3113 _focusedChanged: function(receivedFocusFromKeyboard) { | |
| 3114 if (receivedFocusFromKeyboard) { | |
| 3115 this.ensureRipple(); | |
| 3116 } | |
| 3117 if (this.hasRipple()) { | |
| 3118 this._ripple.holdDown = receivedFocusFromKeyboard; | |
| 3119 } | |
| 3120 }, | |
| 3121 _createRipple: function() { | |
| 3122 var ripple = Polymer.PaperRippleBehavior._createRipple(); | |
| 3123 ripple.id = 'ink'; | |
| 3124 ripple.setAttribute('center', ''); | |
| 3125 ripple.classList.add('circle'); | |
| 3126 return ripple; | |
| 3127 } | |
| 3128 }; | |
| 3129 | |
| 3130 Polymer.PaperInkyFocusBehavior = [ Polymer.IronButtonState, Polymer.IronControlS
tate, Polymer.PaperRippleBehavior, Polymer.PaperInkyFocusBehaviorImpl ]; | |
| 3131 | |
| 3132 Polymer({ | |
| 3133 is: 'paper-icon-button', | |
| 3134 hostAttributes: { | |
| 3135 role: 'button', | |
| 3136 tabindex: '0' | |
| 3137 }, | |
| 3138 behaviors: [ Polymer.PaperInkyFocusBehavior ], | |
| 3139 properties: { | |
| 3140 src: { | |
| 3141 type: String | |
| 3142 }, | |
| 3143 icon: { | |
| 3144 type: String | |
| 3145 }, | |
| 3146 alt: { | |
| 3147 type: String, | |
| 3148 observer: "_altChanged" | |
| 3149 } | |
| 3150 }, | |
| 3151 _altChanged: function(newValue, oldValue) { | |
| 3152 var label = this.getAttribute('aria-label'); | |
| 3153 if (!label || oldValue == label) { | |
| 3154 this.setAttribute('aria-label', newValue); | |
| 3155 } | |
| 3156 } | |
| 3157 }); | |
| 3158 | |
| 3159 Polymer({ | |
| 3160 is: 'paper-tab', | |
| 3161 behaviors: [ Polymer.IronControlState, Polymer.IronButtonState, Polymer.PaperR
ippleBehavior ], | |
| 3162 properties: { | |
| 3163 link: { | |
| 3164 type: Boolean, | |
| 3165 value: false, | |
| 3166 reflectToAttribute: true | |
| 3167 } | |
| 3168 }, | |
| 3169 hostAttributes: { | |
| 3170 role: 'tab' | |
| 3171 }, | |
| 3172 listeners: { | |
| 3173 down: '_updateNoink', | |
| 3174 tap: '_onTap' | |
| 3175 }, | |
| 3176 attached: function() { | |
| 3177 this._updateNoink(); | |
| 3178 }, | |
| 3179 get _parentNoink() { | |
| 3180 var parent = Polymer.dom(this).parentNode; | |
| 3181 return !!parent && !!parent.noink; | |
| 3182 }, | |
| 3183 _updateNoink: function() { | |
| 3184 this.noink = !!this.noink || !!this._parentNoink; | |
| 3185 }, | |
| 3186 _onTap: function(event) { | |
| 3187 if (this.link) { | |
| 3188 var anchor = this.queryEffectiveChildren('a'); | |
| 3189 if (!anchor) { | |
| 3190 return; | |
| 3191 } | |
| 3192 if (event.target === anchor) { | |
| 3193 return; | |
| 3194 } | |
| 3195 anchor.click(); | |
| 3196 } | |
| 3197 } | |
| 3198 }); | |
| 3199 | |
| 3200 Polymer.IronMultiSelectableBehaviorImpl = { | |
| 3201 properties: { | |
| 3202 multi: { | |
| 3203 type: Boolean, | |
| 3204 value: false, | |
| 3205 observer: 'multiChanged' | |
| 3206 }, | |
| 3207 selectedValues: { | |
| 3208 type: Array, | |
| 3209 notify: true | |
| 3210 }, | |
| 3211 selectedItems: { | |
| 3212 type: Array, | |
| 3213 readOnly: true, | |
| 3214 notify: true | |
| 3215 } | |
| 3216 }, | |
| 3217 observers: [ '_updateSelected(selectedValues.splices)' ], | |
| 3218 select: function(value) { | |
| 3219 if (this.multi) { | |
| 3220 if (this.selectedValues) { | |
| 3221 this._toggleSelected(value); | |
| 3222 } else { | |
| 3223 this.selectedValues = [ value ]; | |
| 3224 } | |
| 3225 } else { | |
| 3226 this.selected = value; | |
| 3227 } | |
| 3228 }, | |
| 3229 multiChanged: function(multi) { | |
| 3230 this._selection.multi = multi; | |
| 3231 }, | |
| 3232 get _shouldUpdateSelection() { | |
| 3233 return this.selected != null || this.selectedValues != null && this.selected
Values.length; | |
| 3234 }, | |
| 3235 _updateAttrForSelected: function() { | |
| 3236 if (!this.multi) { | |
| 3237 Polymer.IronSelectableBehavior._updateAttrForSelected.apply(this); | |
| 3238 } else if (this._shouldUpdateSelection) { | |
| 3239 this.selectedValues = this.selectedItems.map(function(selectedItem) { | |
| 3240 return this._indexToValue(this.indexOf(selectedItem)); | |
| 3241 }, this).filter(function(unfilteredValue) { | |
| 3242 return unfilteredValue != null; | |
| 3243 }, this); | |
| 3244 } | |
| 3245 }, | |
| 3246 _updateSelected: function() { | |
| 3247 if (this.multi) { | |
| 3248 this._selectMulti(this.selectedValues); | |
| 3249 } else { | |
| 3250 this._selectSelected(this.selected); | |
| 3251 } | |
| 3252 }, | |
| 3253 _selectMulti: function(values) { | |
| 3254 if (values) { | |
| 3255 var selectedItems = this._valuesToItems(values); | |
| 3256 this._selection.clear(selectedItems); | |
| 3257 for (var i = 0; i < selectedItems.length; i++) { | |
| 3258 this._selection.setItemSelected(selectedItems[i], true); | |
| 3259 } | |
| 3260 if (this.fallbackSelection && this.items.length && !this._selection.get().
length) { | |
| 3261 var fallback = this._valueToItem(this.fallbackSelection); | |
| 3262 if (fallback) { | |
| 3263 this.selectedValues = [ this.fallbackSelection ]; | |
| 3264 } | |
| 3265 } | |
| 3266 } else { | |
| 3267 this._selection.clear(); | |
| 3268 } | |
| 3269 }, | |
| 3270 _selectionChange: function() { | |
| 3271 var s = this._selection.get(); | |
| 3272 if (this.multi) { | |
| 3273 this._setSelectedItems(s); | |
| 3274 } else { | |
| 3275 this._setSelectedItems([ s ]); | |
| 3276 this._setSelectedItem(s); | |
| 3277 } | |
| 3278 }, | |
| 3279 _toggleSelected: function(value) { | |
| 3280 var i = this.selectedValues.indexOf(value); | |
| 3281 var unselected = i < 0; | |
| 3282 if (unselected) { | |
| 3283 this.push('selectedValues', value); | |
| 3284 } else { | |
| 3285 this.splice('selectedValues', i, 1); | |
| 3286 } | |
| 3287 }, | |
| 3288 _valuesToItems: function(values) { | |
| 3289 return values == null ? null : values.map(function(value) { | |
| 3290 return this._valueToItem(value); | |
| 3291 }, this); | |
| 3292 } | |
| 3293 }; | |
| 3294 | |
| 3295 Polymer.IronMultiSelectableBehavior = [ Polymer.IronSelectableBehavior, Polymer.
IronMultiSelectableBehaviorImpl ]; | |
| 3296 | |
| 3297 Polymer.IronMenuBehaviorImpl = { | |
| 3298 properties: { | |
| 3299 focusedItem: { | |
| 3300 observer: '_focusedItemChanged', | |
| 3301 readOnly: true, | |
| 3302 type: Object | |
| 3303 }, | |
| 3304 attrForItemTitle: { | |
| 3305 type: String | |
| 3306 } | |
| 3307 }, | |
| 3308 hostAttributes: { | |
| 3309 role: 'menu', | |
| 3310 tabindex: '0' | |
| 3311 }, | |
| 3312 observers: [ '_updateMultiselectable(multi)' ], | |
| 3313 listeners: { | |
| 3314 focus: '_onFocus', | |
| 3315 keydown: '_onKeydown', | |
| 3316 'iron-items-changed': '_onIronItemsChanged' | |
| 3317 }, | |
| 3318 keyBindings: { | |
| 3319 up: '_onUpKey', | |
| 3320 down: '_onDownKey', | |
| 3321 esc: '_onEscKey', | |
| 3322 'shift+tab:keydown': '_onShiftTabDown' | |
| 3323 }, | |
| 3324 attached: function() { | |
| 3325 this._resetTabindices(); | |
| 3326 }, | |
| 3327 select: function(value) { | |
| 3328 if (this._defaultFocusAsync) { | |
| 3329 this.cancelAsync(this._defaultFocusAsync); | |
| 3330 this._defaultFocusAsync = null; | |
| 3331 } | |
| 3332 var item = this._valueToItem(value); | |
| 3333 if (item && item.hasAttribute('disabled')) return; | |
| 3334 this._setFocusedItem(item); | |
| 3335 Polymer.IronMultiSelectableBehaviorImpl.select.apply(this, arguments); | |
| 3336 }, | |
| 3337 _resetTabindices: function() { | |
| 3338 var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0]
: this.selectedItem; | |
| 3339 this.items.forEach(function(item) { | |
| 3340 item.setAttribute('tabindex', item === selectedItem ? '0' : '-1'); | |
| 3341 }, this); | |
| 3342 }, | |
| 3343 _updateMultiselectable: function(multi) { | |
| 3344 if (multi) { | |
| 3345 this.setAttribute('aria-multiselectable', 'true'); | |
| 3346 } else { | |
| 3347 this.removeAttribute('aria-multiselectable'); | |
| 3348 } | |
| 3349 }, | |
| 3350 _focusWithKeyboardEvent: function(event) { | |
| 3351 for (var i = 0, item; item = this.items[i]; i++) { | |
| 3352 var attr = this.attrForItemTitle || 'textContent'; | |
| 3353 var title = item[attr] || item.getAttribute(attr); | |
| 3354 if (!item.hasAttribute('disabled') && title && title.trim().charAt(0).toLo
werCase() === String.fromCharCode(event.keyCode).toLowerCase()) { | |
| 3355 this._setFocusedItem(item); | |
| 3356 break; | |
| 3357 } | |
| 3358 } | |
| 3359 }, | |
| 3360 _focusPrevious: function() { | |
| 3361 var length = this.items.length; | |
| 3362 var curFocusIndex = Number(this.indexOf(this.focusedItem)); | |
| 3363 for (var i = 1; i < length + 1; i++) { | |
| 3364 var item = this.items[(curFocusIndex - i + length) % length]; | |
| 3365 if (!item.hasAttribute('disabled')) { | |
| 3366 this._setFocusedItem(item); | |
| 3367 return; | |
| 3368 } | |
| 3369 } | |
| 3370 }, | |
| 3371 _focusNext: function() { | |
| 3372 var length = this.items.length; | |
| 3373 var curFocusIndex = Number(this.indexOf(this.focusedItem)); | |
| 3374 for (var i = 1; i < length + 1; i++) { | |
| 3375 var item = this.items[(curFocusIndex + i) % length]; | |
| 3376 if (!item.hasAttribute('disabled')) { | |
| 3377 this._setFocusedItem(item); | |
| 3378 return; | |
| 3379 } | |
| 3380 } | |
| 3381 }, | |
| 3382 _applySelection: function(item, isSelected) { | |
| 3383 if (isSelected) { | |
| 3384 item.setAttribute('aria-selected', 'true'); | |
| 3385 } else { | |
| 3386 item.removeAttribute('aria-selected'); | |
| 3387 } | |
| 3388 Polymer.IronSelectableBehavior._applySelection.apply(this, arguments); | |
| 3389 }, | |
| 3390 _focusedItemChanged: function(focusedItem, old) { | |
| 3391 old && old.setAttribute('tabindex', '-1'); | |
| 3392 if (focusedItem) { | |
| 3393 focusedItem.setAttribute('tabindex', '0'); | |
| 3394 focusedItem.focus(); | |
| 3395 } | |
| 3396 }, | |
| 3397 _onIronItemsChanged: function(event) { | |
| 3398 if (event.detail.addedNodes.length) { | |
| 3399 this._resetTabindices(); | |
| 3400 } | |
| 3401 }, | |
| 3402 _onShiftTabDown: function(event) { | |
| 3403 var oldTabIndex = this.getAttribute('tabindex'); | |
| 3404 Polymer.IronMenuBehaviorImpl._shiftTabPressed = true; | |
| 3405 this._setFocusedItem(null); | |
| 3406 this.setAttribute('tabindex', '-1'); | |
| 3407 this.async(function() { | |
| 3408 this.setAttribute('tabindex', oldTabIndex); | |
| 3409 Polymer.IronMenuBehaviorImpl._shiftTabPressed = false; | |
| 3410 }, 1); | |
| 3411 }, | |
| 3412 _onFocus: function(event) { | |
| 3413 if (Polymer.IronMenuBehaviorImpl._shiftTabPressed) { | |
| 3414 return; | |
| 3415 } | |
| 3416 var rootTarget = Polymer.dom(event).rootTarget; | |
| 3417 if (rootTarget !== this && typeof rootTarget.tabIndex !== "undefined" && !th
is.isLightDescendant(rootTarget)) { | |
| 3418 return; | |
| 3419 } | |
| 3420 this._defaultFocusAsync = this.async(function() { | |
| 3421 var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0
] : this.selectedItem; | |
| 3422 this._setFocusedItem(null); | |
| 3423 if (selectedItem) { | |
| 3424 this._setFocusedItem(selectedItem); | |
| 3425 } else if (this.items[0]) { | |
| 3426 this._focusNext(); | |
| 3427 } | |
| 3428 }); | |
| 3429 }, | |
| 3430 _onUpKey: function(event) { | |
| 3431 this._focusPrevious(); | |
| 3432 event.detail.keyboardEvent.preventDefault(); | |
| 3433 }, | |
| 3434 _onDownKey: function(event) { | |
| 3435 this._focusNext(); | |
| 3436 event.detail.keyboardEvent.preventDefault(); | |
| 3437 }, | |
| 3438 _onEscKey: function(event) { | |
| 3439 this.focusedItem.blur(); | |
| 3440 }, | |
| 3441 _onKeydown: function(event) { | |
| 3442 if (!this.keyboardEventMatchesKeys(event, 'up down esc')) { | |
| 3443 this._focusWithKeyboardEvent(event); | |
| 3444 } | |
| 3445 event.stopPropagation(); | |
| 3446 }, | |
| 3447 _activateHandler: function(event) { | |
| 3448 Polymer.IronSelectableBehavior._activateHandler.call(this, event); | |
| 3449 event.stopPropagation(); | |
| 3450 } | |
| 3451 }; | |
| 3452 | |
| 3453 Polymer.IronMenuBehaviorImpl._shiftTabPressed = false; | |
| 3454 | |
| 3455 Polymer.IronMenuBehavior = [ Polymer.IronMultiSelectableBehavior, Polymer.IronA1
1yKeysBehavior, Polymer.IronMenuBehaviorImpl ]; | |
| 3456 | |
| 3457 Polymer.IronMenubarBehaviorImpl = { | |
| 3458 hostAttributes: { | |
| 3459 role: 'menubar' | |
| 3460 }, | |
| 3461 keyBindings: { | |
| 3462 left: '_onLeftKey', | |
| 3463 right: '_onRightKey' | |
| 3464 }, | |
| 3465 _onUpKey: function(event) { | |
| 3466 this.focusedItem.click(); | |
| 3467 event.detail.keyboardEvent.preventDefault(); | |
| 3468 }, | |
| 3469 _onDownKey: function(event) { | |
| 3470 this.focusedItem.click(); | |
| 3471 event.detail.keyboardEvent.preventDefault(); | |
| 3472 }, | |
| 3473 get _isRTL() { | |
| 3474 return window.getComputedStyle(this)['direction'] === 'rtl'; | |
| 3475 }, | |
| 3476 _onLeftKey: function(event) { | |
| 3477 if (this._isRTL) { | |
| 3478 this._focusNext(); | |
| 3479 } else { | |
| 3480 this._focusPrevious(); | |
| 3481 } | |
| 3482 event.detail.keyboardEvent.preventDefault(); | |
| 3483 }, | |
| 3484 _onRightKey: function(event) { | |
| 3485 if (this._isRTL) { | |
| 3486 this._focusPrevious(); | |
| 3487 } else { | |
| 3488 this._focusNext(); | |
| 3489 } | |
| 3490 event.detail.keyboardEvent.preventDefault(); | |
| 3491 }, | |
| 3492 _onKeydown: function(event) { | |
| 3493 if (this.keyboardEventMatchesKeys(event, 'up down left right esc')) { | |
| 3494 return; | |
| 3495 } | |
| 3496 this._focusWithKeyboardEvent(event); | |
| 3497 } | |
| 3498 }; | |
| 3499 | |
| 3500 Polymer.IronMenubarBehavior = [ Polymer.IronMenuBehavior, Polymer.IronMenubarBeh
aviorImpl ]; | |
| 3501 | |
| 3502 Polymer({ | |
| 3503 is: 'iron-iconset-svg', | |
| 3504 properties: { | |
| 3505 name: { | |
| 3506 type: String, | |
| 3507 observer: '_nameChanged' | |
| 3508 }, | |
| 3509 size: { | |
| 3510 type: Number, | |
| 3511 value: 24 | |
| 3512 } | |
| 3513 }, | |
| 3514 attached: function() { | |
| 3515 this.style.display = 'none'; | |
| 3516 }, | |
| 3517 getIconNames: function() { | |
| 3518 this._icons = this._createIconMap(); | |
| 3519 return Object.keys(this._icons).map(function(n) { | |
| 3520 return this.name + ':' + n; | |
| 3521 }, this); | |
| 3522 }, | |
| 3523 applyIcon: function(element, iconName) { | |
| 3524 element = element.root || element; | |
| 3525 this.removeIcon(element); | |
| 3526 var svg = this._cloneIcon(iconName); | |
| 3527 if (svg) { | |
| 3528 var pde = Polymer.dom(element); | |
| 3529 pde.insertBefore(svg, pde.childNodes[0]); | |
| 3530 return element._svgIcon = svg; | |
| 3531 } | |
| 3532 return null; | |
| 3533 }, | |
| 3534 removeIcon: function(element) { | |
| 3535 if (element._svgIcon) { | |
| 3536 Polymer.dom(element).removeChild(element._svgIcon); | |
| 3537 element._svgIcon = null; | |
| 3538 } | |
| 3539 }, | |
| 3540 _nameChanged: function() { | |
| 3541 new Polymer.IronMeta({ | |
| 3542 type: 'iconset', | |
| 3543 key: this.name, | |
| 3544 value: this | |
| 3545 }); | |
| 3546 this.async(function() { | |
| 3547 this.fire('iron-iconset-added', this, { | |
| 3548 node: window | |
| 3549 }); | |
| 3550 }); | |
| 3551 }, | |
| 3552 _createIconMap: function() { | |
| 3553 var icons = Object.create(null); | |
| 3554 Polymer.dom(this).querySelectorAll('[id]').forEach(function(icon) { | |
| 3555 icons[icon.id] = icon; | |
| 3556 }); | |
| 3557 return icons; | |
| 3558 }, | |
| 3559 _cloneIcon: function(id) { | |
| 3560 this._icons = this._icons || this._createIconMap(); | |
| 3561 return this._prepareSvgClone(this._icons[id], this.size); | |
| 3562 }, | |
| 3563 _prepareSvgClone: function(sourceSvg, size) { | |
| 3564 if (sourceSvg) { | |
| 3565 var content = sourceSvg.cloneNode(true), svg = document.createElementNS('h
ttp://www.w3.org/2000/svg', 'svg'), viewBox = content.getAttribute('viewBox') ||
'0 0 ' + size + ' ' + size; | |
| 3566 svg.setAttribute('viewBox', viewBox); | |
| 3567 svg.setAttribute('preserveAspectRatio', 'xMidYMid meet'); | |
| 3568 svg.style.cssText = 'pointer-events: none; display: block; width: 100%; he
ight: 100%;'; | |
| 3569 svg.appendChild(content).removeAttribute('id'); | |
| 3570 return svg; | |
| 3571 } | |
| 3572 return null; | |
| 3573 } | |
| 3574 }); | |
| 3575 | |
| 3576 Polymer({ | |
| 3577 is: 'paper-tabs', | |
| 3578 behaviors: [ Polymer.IronResizableBehavior, Polymer.IronMenubarBehavior ], | |
| 3579 properties: { | |
| 3580 noink: { | |
| 3581 type: Boolean, | |
| 3582 value: false, | |
| 3583 observer: '_noinkChanged' | |
| 3584 }, | |
| 3585 noBar: { | |
| 3586 type: Boolean, | |
| 3587 value: false | |
| 3588 }, | |
| 3589 noSlide: { | |
| 3590 type: Boolean, | |
| 3591 value: false | |
| 3592 }, | |
| 3593 scrollable: { | |
| 3594 type: Boolean, | |
| 3595 value: false | |
| 3596 }, | |
| 3597 fitContainer: { | |
| 3598 type: Boolean, | |
| 3599 value: false | |
| 3600 }, | |
| 3601 disableDrag: { | |
| 3602 type: Boolean, | |
| 3603 value: false | |
| 3604 }, | |
| 3605 hideScrollButtons: { | |
| 3606 type: Boolean, | |
| 3607 value: false | |
| 3608 }, | |
| 3609 alignBottom: { | |
| 3610 type: Boolean, | |
| 3611 value: false | |
| 3612 }, | |
| 3613 selectable: { | |
| 3614 type: String, | |
| 3615 value: 'paper-tab' | |
| 3616 }, | |
| 3617 autoselect: { | |
| 3618 type: Boolean, | |
| 3619 value: false | |
| 3620 }, | |
| 3621 autoselectDelay: { | |
| 3622 type: Number, | |
| 3623 value: 0 | |
| 3624 }, | |
| 3625 _step: { | |
| 3626 type: Number, | |
| 3627 value: 10 | |
| 3628 }, | |
| 3629 _holdDelay: { | |
| 3630 type: Number, | |
| 3631 value: 1 | |
| 3632 }, | |
| 3633 _leftHidden: { | |
| 3634 type: Boolean, | |
| 3635 value: false | |
| 3636 }, | |
| 3637 _rightHidden: { | |
| 3638 type: Boolean, | |
| 3639 value: false | |
| 3640 }, | |
| 3641 _previousTab: { | |
| 3642 type: Object | |
| 3643 } | |
| 3644 }, | |
| 3645 hostAttributes: { | |
| 3646 role: 'tablist' | |
| 3647 }, | |
| 3648 listeners: { | |
| 3649 'iron-resize': '_onTabSizingChanged', | |
| 3650 'iron-items-changed': '_onTabSizingChanged', | |
| 3651 'iron-select': '_onIronSelect', | |
| 3652 'iron-deselect': '_onIronDeselect' | |
| 3653 }, | |
| 3654 keyBindings: { | |
| 3655 'left:keyup right:keyup': '_onArrowKeyup' | |
| 3656 }, | |
| 3657 created: function() { | |
| 3658 this._holdJob = null; | |
| 3659 this._pendingActivationItem = undefined; | |
| 3660 this._pendingActivationTimeout = undefined; | |
| 3661 this._bindDelayedActivationHandler = this._delayedActivationHandler.bind(thi
s); | |
| 3662 this.addEventListener('blur', this._onBlurCapture.bind(this), true); | |
| 3663 }, | |
| 3664 ready: function() { | |
| 3665 this.setScrollDirection('y', this.$.tabsContainer); | |
| 3666 }, | |
| 3667 detached: function() { | |
| 3668 this._cancelPendingActivation(); | |
| 3669 }, | |
| 3670 _noinkChanged: function(noink) { | |
| 3671 var childTabs = Polymer.dom(this).querySelectorAll('paper-tab'); | |
| 3672 childTabs.forEach(noink ? this._setNoinkAttribute : this._removeNoinkAttribu
te); | |
| 3673 }, | |
| 3674 _setNoinkAttribute: function(element) { | |
| 3675 element.setAttribute('noink', ''); | |
| 3676 }, | |
| 3677 _removeNoinkAttribute: function(element) { | |
| 3678 element.removeAttribute('noink'); | |
| 3679 }, | |
| 3680 _computeScrollButtonClass: function(hideThisButton, scrollable, hideScrollButt
ons) { | |
| 3681 if (!scrollable || hideScrollButtons) { | |
| 3682 return 'hidden'; | |
| 3683 } | |
| 3684 if (hideThisButton) { | |
| 3685 return 'not-visible'; | |
| 3686 } | |
| 3687 return ''; | |
| 3688 }, | |
| 3689 _computeTabsContentClass: function(scrollable, fitContainer) { | |
| 3690 return scrollable ? 'scrollable' + (fitContainer ? ' fit-container' : '') :
' fit-container'; | |
| 3691 }, | |
| 3692 _computeSelectionBarClass: function(noBar, alignBottom) { | |
| 3693 if (noBar) { | |
| 3694 return 'hidden'; | |
| 3695 } else if (alignBottom) { | |
| 3696 return 'align-bottom'; | |
| 3697 } | |
| 3698 return ''; | |
| 3699 }, | |
| 3700 _onTabSizingChanged: function() { | |
| 3701 this.debounce('_onTabSizingChanged', function() { | |
| 3702 this._scroll(); | |
| 3703 this._tabChanged(this.selectedItem); | |
| 3704 }, 10); | |
| 3705 }, | |
| 3706 _onIronSelect: function(event) { | |
| 3707 this._tabChanged(event.detail.item, this._previousTab); | |
| 3708 this._previousTab = event.detail.item; | |
| 3709 this.cancelDebouncer('tab-changed'); | |
| 3710 }, | |
| 3711 _onIronDeselect: function(event) { | |
| 3712 this.debounce('tab-changed', function() { | |
| 3713 this._tabChanged(null, this._previousTab); | |
| 3714 this._previousTab = null; | |
| 3715 }, 1); | |
| 3716 }, | |
| 3717 _activateHandler: function() { | |
| 3718 this._cancelPendingActivation(); | |
| 3719 Polymer.IronMenuBehaviorImpl._activateHandler.apply(this, arguments); | |
| 3720 }, | |
| 3721 _scheduleActivation: function(item, delay) { | |
| 3722 this._pendingActivationItem = item; | |
| 3723 this._pendingActivationTimeout = this.async(this._bindDelayedActivationHandl
er, delay); | |
| 3724 }, | |
| 3725 _delayedActivationHandler: function() { | |
| 3726 var item = this._pendingActivationItem; | |
| 3727 this._pendingActivationItem = undefined; | |
| 3728 this._pendingActivationTimeout = undefined; | |
| 3729 item.fire(this.activateEvent, null, { | |
| 3730 bubbles: true, | |
| 3731 cancelable: true | |
| 3732 }); | |
| 3733 }, | |
| 3734 _cancelPendingActivation: function() { | |
| 3735 if (this._pendingActivationTimeout !== undefined) { | |
| 3736 this.cancelAsync(this._pendingActivationTimeout); | |
| 3737 this._pendingActivationItem = undefined; | |
| 3738 this._pendingActivationTimeout = undefined; | |
| 3739 } | |
| 3740 }, | |
| 3741 _onArrowKeyup: function(event) { | |
| 3742 if (this.autoselect) { | |
| 3743 this._scheduleActivation(this.focusedItem, this.autoselectDelay); | |
| 3744 } | |
| 3745 }, | |
| 3746 _onBlurCapture: function(event) { | |
| 3747 if (event.target === this._pendingActivationItem) { | |
| 3748 this._cancelPendingActivation(); | |
| 3749 } | |
| 3750 }, | |
| 3751 get _tabContainerScrollSize() { | |
| 3752 return Math.max(0, this.$.tabsContainer.scrollWidth - this.$.tabsContainer.o
ffsetWidth); | |
| 3753 }, | |
| 3754 _scroll: function(e, detail) { | |
| 3755 if (!this.scrollable) { | |
| 3756 return; | |
| 3757 } | |
| 3758 var ddx = detail && -detail.ddx || 0; | |
| 3759 this._affectScroll(ddx); | |
| 3760 }, | |
| 3761 _down: function(e) { | |
| 3762 this.async(function() { | |
| 3763 if (this._defaultFocusAsync) { | |
| 3764 this.cancelAsync(this._defaultFocusAsync); | |
| 3765 this._defaultFocusAsync = null; | |
| 3766 } | |
| 3767 }, 1); | |
| 3768 }, | |
| 3769 _affectScroll: function(dx) { | |
| 3770 this.$.tabsContainer.scrollLeft += dx; | |
| 3771 var scrollLeft = this.$.tabsContainer.scrollLeft; | |
| 3772 this._leftHidden = scrollLeft === 0; | |
| 3773 this._rightHidden = scrollLeft === this._tabContainerScrollSize; | |
| 3774 }, | |
| 3775 _onLeftScrollButtonDown: function() { | |
| 3776 this._scrollToLeft(); | |
| 3777 this._holdJob = setInterval(this._scrollToLeft.bind(this), this._holdDelay); | |
| 3778 }, | |
| 3779 _onRightScrollButtonDown: function() { | |
| 3780 this._scrollToRight(); | |
| 3781 this._holdJob = setInterval(this._scrollToRight.bind(this), this._holdDelay)
; | |
| 3782 }, | |
| 3783 _onScrollButtonUp: function() { | |
| 3784 clearInterval(this._holdJob); | |
| 3785 this._holdJob = null; | |
| 3786 }, | |
| 3787 _scrollToLeft: function() { | |
| 3788 this._affectScroll(-this._step); | |
| 3789 }, | |
| 3790 _scrollToRight: function() { | |
| 3791 this._affectScroll(this._step); | |
| 3792 }, | |
| 3793 _tabChanged: function(tab, old) { | |
| 3794 if (!tab) { | |
| 3795 this.$.selectionBar.classList.remove('expand'); | |
| 3796 this.$.selectionBar.classList.remove('contract'); | |
| 3797 this._positionBar(0, 0); | |
| 3798 return; | |
| 3799 } | |
| 3800 var r = this.$.tabsContent.getBoundingClientRect(); | |
| 3801 var w = r.width; | |
| 3802 var tabRect = tab.getBoundingClientRect(); | |
| 3803 var tabOffsetLeft = tabRect.left - r.left; | |
| 3804 this._pos = { | |
| 3805 width: this._calcPercent(tabRect.width, w), | |
| 3806 left: this._calcPercent(tabOffsetLeft, w) | |
| 3807 }; | |
| 3808 if (this.noSlide || old == null) { | |
| 3809 this.$.selectionBar.classList.remove('expand'); | |
| 3810 this.$.selectionBar.classList.remove('contract'); | |
| 3811 this._positionBar(this._pos.width, this._pos.left); | |
| 3812 return; | |
| 3813 } | |
| 3814 var oldRect = old.getBoundingClientRect(); | |
| 3815 var oldIndex = this.items.indexOf(old); | |
| 3816 var index = this.items.indexOf(tab); | |
| 3817 var m = 5; | |
| 3818 this.$.selectionBar.classList.add('expand'); | |
| 3819 var moveRight = oldIndex < index; | |
| 3820 var isRTL = this._isRTL; | |
| 3821 if (isRTL) { | |
| 3822 moveRight = !moveRight; | |
| 3823 } | |
| 3824 if (moveRight) { | |
| 3825 this._positionBar(this._calcPercent(tabRect.left + tabRect.width - oldRect
.left, w) - m, this._left); | |
| 3826 } else { | |
| 3827 this._positionBar(this._calcPercent(oldRect.left + oldRect.width - tabRect
.left, w) - m, this._calcPercent(tabOffsetLeft, w) + m); | |
| 3828 } | |
| 3829 if (this.scrollable) { | |
| 3830 this._scrollToSelectedIfNeeded(tabRect.width, tabOffsetLeft); | |
| 3831 } | |
| 3832 }, | |
| 3833 _scrollToSelectedIfNeeded: function(tabWidth, tabOffsetLeft) { | |
| 3834 var l = tabOffsetLeft - this.$.tabsContainer.scrollLeft; | |
| 3835 if (l < 0) { | |
| 3836 this.$.tabsContainer.scrollLeft += l; | |
| 3837 } else { | |
| 3838 l += tabWidth - this.$.tabsContainer.offsetWidth; | |
| 3839 if (l > 0) { | |
| 3840 this.$.tabsContainer.scrollLeft += l; | |
| 3841 } | |
| 3842 } | |
| 3843 }, | |
| 3844 _calcPercent: function(w, w0) { | |
| 3845 return 100 * w / w0; | |
| 3846 }, | |
| 3847 _positionBar: function(width, left) { | |
| 3848 width = width || 0; | |
| 3849 left = left || 0; | |
| 3850 this._width = width; | |
| 3851 this._left = left; | |
| 3852 this.transform('translateX(' + left + '%) scaleX(' + width / 100 + ')', this
.$.selectionBar); | |
| 3853 }, | |
| 3854 _onBarTransitionEnd: function(e) { | |
| 3855 var cl = this.$.selectionBar.classList; | |
| 3856 if (cl.contains('expand')) { | |
| 3857 cl.remove('expand'); | |
| 3858 cl.add('contract'); | |
| 3859 this._positionBar(this._pos.width, this._pos.left); | |
| 3860 } else if (cl.contains('contract')) { | |
| 3861 cl.remove('contract'); | |
| 3862 } | |
| 3863 } | |
| 3864 }); | |
| 3865 | |
| 3866 (function() { | |
| 3867 'use strict'; | |
| 3868 Polymer.IronA11yAnnouncer = Polymer({ | |
| 3869 is: 'iron-a11y-announcer', | |
| 3870 properties: { | |
| 3871 mode: { | |
| 3872 type: String, | |
| 3873 value: 'polite' | |
| 3874 }, | |
| 3875 _text: { | |
| 3876 type: String, | |
| 3877 value: '' | |
| 3878 } | |
| 3879 }, | |
| 3880 created: function() { | |
| 3881 if (!Polymer.IronA11yAnnouncer.instance) { | |
| 3882 Polymer.IronA11yAnnouncer.instance = this; | |
| 3883 } | |
| 3884 document.body.addEventListener('iron-announce', this._onIronAnnounce.bind(
this)); | |
| 3885 }, | |
| 3886 announce: function(text) { | |
| 3887 this._text = ''; | |
| 3888 this.async(function() { | |
| 3889 this._text = text; | |
| 3890 }, 100); | |
| 3891 }, | |
| 3892 _onIronAnnounce: function(event) { | |
| 3893 if (event.detail && event.detail.text) { | |
| 3894 this.announce(event.detail.text); | |
| 3895 } | |
| 3896 } | |
| 3897 }); | |
| 3898 Polymer.IronA11yAnnouncer.instance = null; | |
| 3899 Polymer.IronA11yAnnouncer.requestAvailability = function() { | |
| 3900 if (!Polymer.IronA11yAnnouncer.instance) { | |
| 3901 Polymer.IronA11yAnnouncer.instance = document.createElement('iron-a11y-ann
ouncer'); | |
| 3902 } | |
| 3903 document.body.appendChild(Polymer.IronA11yAnnouncer.instance); | |
| 3904 }; | |
| 3905 })(); | |
| 3906 | |
| 3907 Polymer.IronValidatableBehaviorMeta = null; | |
| 3908 | |
| 3909 Polymer.IronValidatableBehavior = { | |
| 3910 properties: { | |
| 3911 validator: { | |
| 3912 type: String | |
| 3913 }, | |
| 3914 invalid: { | |
| 3915 notify: true, | |
| 3916 reflectToAttribute: true, | |
| 3917 type: Boolean, | |
| 3918 value: false | |
| 3919 }, | |
| 3920 _validatorMeta: { | |
| 3921 type: Object | |
| 3922 }, | |
| 3923 validatorType: { | |
| 3924 type: String, | |
| 3925 value: 'validator' | |
| 3926 }, | |
| 3927 _validator: { | |
| 3928 type: Object, | |
| 3929 computed: '__computeValidator(validator)' | |
| 3930 } | |
| 3931 }, | |
| 3932 observers: [ '_invalidChanged(invalid)' ], | |
| 3933 registered: function() { | |
| 3934 Polymer.IronValidatableBehaviorMeta = new Polymer.IronMeta({ | |
| 3935 type: 'validator' | |
| 3936 }); | |
| 3937 }, | |
| 3938 _invalidChanged: function() { | |
| 3939 if (this.invalid) { | |
| 3940 this.setAttribute('aria-invalid', 'true'); | |
| 3941 } else { | |
| 3942 this.removeAttribute('aria-invalid'); | |
| 3943 } | |
| 3944 }, | |
| 3945 hasValidator: function() { | |
| 3946 return this._validator != null; | |
| 3947 }, | |
| 3948 validate: function(value) { | |
| 3949 this.invalid = !this._getValidity(value); | |
| 3950 return !this.invalid; | |
| 3951 }, | |
| 3952 _getValidity: function(value) { | |
| 3953 if (this.hasValidator()) { | |
| 3954 return this._validator.validate(value); | |
| 3955 } | |
| 3956 return true; | |
| 3957 }, | |
| 3958 __computeValidator: function() { | |
| 3959 return Polymer.IronValidatableBehaviorMeta && Polymer.IronValidatableBehavio
rMeta.byKey(this.validator); | |
| 3960 } | |
| 3961 }; | |
| 3962 | |
| 3963 Polymer({ | |
| 3964 is: 'iron-input', | |
| 3965 "extends": 'input', | |
| 3966 behaviors: [ Polymer.IronValidatableBehavior ], | |
| 3967 properties: { | |
| 3968 bindValue: { | |
| 3969 observer: '_bindValueChanged', | |
| 3970 type: String | |
| 3971 }, | |
| 3972 preventInvalidInput: { | |
| 3973 type: Boolean | |
| 3974 }, | |
| 3975 allowedPattern: { | |
| 3976 type: String, | |
| 3977 observer: "_allowedPatternChanged" | |
| 3978 }, | |
| 3979 _previousValidInput: { | |
| 3980 type: String, | |
| 3981 value: '' | |
| 3982 }, | |
| 3983 _patternAlreadyChecked: { | |
| 3984 type: Boolean, | |
| 3985 value: false | |
| 3986 } | |
| 3987 }, | |
| 3988 listeners: { | |
| 3989 input: '_onInput', | |
| 3990 keypress: '_onKeypress' | |
| 3991 }, | |
| 3992 registered: function() { | |
| 3993 if (!this._canDispatchEventOnDisabled()) { | |
| 3994 this._origDispatchEvent = this.dispatchEvent; | |
| 3995 this.dispatchEvent = this._dispatchEventFirefoxIE; | |
| 3996 } | |
| 3997 }, | |
| 3998 created: function() { | |
| 3999 Polymer.IronA11yAnnouncer.requestAvailability(); | |
| 4000 }, | |
| 4001 _canDispatchEventOnDisabled: function() { | |
| 4002 var input = document.createElement('input'); | |
| 4003 var canDispatch = false; | |
| 4004 input.disabled = true; | |
| 4005 input.addEventListener('feature-check-dispatch-event', function() { | |
| 4006 canDispatch = true; | |
| 4007 }); | |
| 4008 try { | |
| 4009 input.dispatchEvent(new Event('feature-check-dispatch-event')); | |
| 4010 } catch (e) {} | |
| 4011 return canDispatch; | |
| 4012 }, | |
| 4013 _dispatchEventFirefoxIE: function() { | |
| 4014 var disabled = this.disabled; | |
| 4015 this.disabled = false; | |
| 4016 this._origDispatchEvent.apply(this, arguments); | |
| 4017 this.disabled = disabled; | |
| 4018 }, | |
| 4019 get _patternRegExp() { | |
| 4020 var pattern; | |
| 4021 if (this.allowedPattern) { | |
| 4022 pattern = new RegExp(this.allowedPattern); | |
| 4023 } else { | |
| 4024 switch (this.type) { | |
| 4025 case 'number': | |
| 4026 pattern = /[0-9.,e-]/; | |
| 4027 break; | |
| 4028 } | |
| 4029 } | |
| 4030 return pattern; | |
| 4031 }, | |
| 4032 ready: function() { | |
| 4033 this.bindValue = this.value; | |
| 4034 }, | |
| 4035 _bindValueChanged: function() { | |
| 4036 if (this.value !== this.bindValue) { | |
| 4037 this.value = !(this.bindValue || this.bindValue === 0 || this.bindValue ==
= false) ? '' : this.bindValue; | |
| 4038 } | |
| 4039 this.fire('bind-value-changed', { | |
| 4040 value: this.bindValue | |
| 4041 }); | |
| 4042 }, | |
| 4043 _allowedPatternChanged: function() { | |
| 4044 this.preventInvalidInput = this.allowedPattern ? true : false; | |
| 4045 }, | |
| 4046 _onInput: function() { | |
| 4047 if (this.preventInvalidInput && !this._patternAlreadyChecked) { | |
| 4048 var valid = this._checkPatternValidity(); | |
| 4049 if (!valid) { | |
| 4050 this._announceInvalidCharacter('Invalid string of characters not entered
.'); | |
| 4051 this.value = this._previousValidInput; | |
| 4052 } | |
| 4053 } | |
| 4054 this.bindValue = this.value; | |
| 4055 this._previousValidInput = this.value; | |
| 4056 this._patternAlreadyChecked = false; | |
| 4057 }, | |
| 4058 _isPrintable: function(event) { | |
| 4059 var anyNonPrintable = event.keyCode == 8 || event.keyCode == 9 || event.keyC
ode == 13 || event.keyCode == 27; | |
| 4060 var mozNonPrintable = event.keyCode == 19 || event.keyCode == 20 || event.ke
yCode == 45 || event.keyCode == 46 || event.keyCode == 144 || event.keyCode == 1
45 || event.keyCode > 32 && event.keyCode < 41 || event.keyCode > 111 && event.k
eyCode < 124; | |
| 4061 return !anyNonPrintable && !(event.charCode == 0 && mozNonPrintable); | |
| 4062 }, | |
| 4063 _onKeypress: function(event) { | |
| 4064 if (!this.preventInvalidInput && this.type !== 'number') { | |
| 4065 return; | |
| 4066 } | |
| 4067 var regexp = this._patternRegExp; | |
| 4068 if (!regexp) { | |
| 4069 return; | |
| 4070 } | |
| 4071 if (event.metaKey || event.ctrlKey || event.altKey) return; | |
| 4072 this._patternAlreadyChecked = true; | |
| 4073 var thisChar = String.fromCharCode(event.charCode); | |
| 4074 if (this._isPrintable(event) && !regexp.test(thisChar)) { | |
| 4075 event.preventDefault(); | |
| 4076 this._announceInvalidCharacter('Invalid character ' + thisChar + ' not ent
ered.'); | |
| 4077 } | |
| 4078 }, | |
| 4079 _checkPatternValidity: function() { | |
| 4080 var regexp = this._patternRegExp; | |
| 4081 if (!regexp) { | |
| 4082 return true; | |
| 4083 } | |
| 4084 for (var i = 0; i < this.value.length; i++) { | |
| 4085 if (!regexp.test(this.value[i])) { | |
| 4086 return false; | |
| 4087 } | |
| 4088 } | |
| 4089 return true; | |
| 4090 }, | |
| 4091 validate: function() { | |
| 4092 var valid = this.checkValidity(); | |
| 4093 if (valid) { | |
| 4094 if (this.required && this.value === '') { | |
| 4095 valid = false; | |
| 4096 } else if (this.hasValidator()) { | |
| 4097 valid = Polymer.IronValidatableBehavior.validate.call(this, this.value); | |
| 4098 } | |
| 4099 } | |
| 4100 this.invalid = !valid; | |
| 4101 this.fire('iron-input-validate'); | |
| 4102 return valid; | |
| 4103 }, | |
| 4104 _announceInvalidCharacter: function(message) { | |
| 4105 this.fire('iron-announce', { | |
| 4106 text: message | |
| 4107 }); | |
| 4108 } | |
| 4109 }); | |
| 4110 | |
| 4111 Polymer({ | |
| 4112 is: 'paper-input-container', | |
| 4113 properties: { | |
| 4114 noLabelFloat: { | |
| 4115 type: Boolean, | |
| 4116 value: false | |
| 4117 }, | |
| 4118 alwaysFloatLabel: { | |
| 4119 type: Boolean, | |
| 4120 value: false | |
| 4121 }, | |
| 4122 attrForValue: { | |
| 4123 type: String, | |
| 4124 value: 'bind-value' | |
| 4125 }, | |
| 4126 autoValidate: { | |
| 4127 type: Boolean, | |
| 4128 value: false | |
| 4129 }, | |
| 4130 invalid: { | |
| 4131 observer: '_invalidChanged', | |
| 4132 type: Boolean, | |
| 4133 value: false | |
| 4134 }, | |
| 4135 focused: { | |
| 4136 readOnly: true, | |
| 4137 type: Boolean, | |
| 4138 value: false, | |
| 4139 notify: true | |
| 4140 }, | |
| 4141 _addons: { | |
| 4142 type: Array | |
| 4143 }, | |
| 4144 _inputHasContent: { | |
| 4145 type: Boolean, | |
| 4146 value: false | |
| 4147 }, | |
| 4148 _inputSelector: { | |
| 4149 type: String, | |
| 4150 value: 'input,textarea,.paper-input-input' | |
| 4151 }, | |
| 4152 _boundOnFocus: { | |
| 4153 type: Function, | |
| 4154 value: function() { | |
| 4155 return this._onFocus.bind(this); | |
| 4156 } | |
| 4157 }, | |
| 4158 _boundOnBlur: { | |
| 4159 type: Function, | |
| 4160 value: function() { | |
| 4161 return this._onBlur.bind(this); | |
| 4162 } | |
| 4163 }, | |
| 4164 _boundOnInput: { | |
| 4165 type: Function, | |
| 4166 value: function() { | |
| 4167 return this._onInput.bind(this); | |
| 4168 } | |
| 4169 }, | |
| 4170 _boundValueChanged: { | |
| 4171 type: Function, | |
| 4172 value: function() { | |
| 4173 return this._onValueChanged.bind(this); | |
| 4174 } | |
| 4175 } | |
| 4176 }, | |
| 4177 listeners: { | |
| 4178 'addon-attached': '_onAddonAttached', | |
| 4179 'iron-input-validate': '_onIronInputValidate' | |
| 4180 }, | |
| 4181 get _valueChangedEvent() { | |
| 4182 return this.attrForValue + '-changed'; | |
| 4183 }, | |
| 4184 get _propertyForValue() { | |
| 4185 return Polymer.CaseMap.dashToCamelCase(this.attrForValue); | |
| 4186 }, | |
| 4187 get _inputElement() { | |
| 4188 return Polymer.dom(this).querySelector(this._inputSelector); | |
| 4189 }, | |
| 4190 get _inputElementValue() { | |
| 4191 return this._inputElement[this._propertyForValue] || this._inputElement.valu
e; | |
| 4192 }, | |
| 4193 ready: function() { | |
| 4194 if (!this._addons) { | |
| 4195 this._addons = []; | |
| 4196 } | |
| 4197 this.addEventListener('focus', this._boundOnFocus, true); | |
| 4198 this.addEventListener('blur', this._boundOnBlur, true); | |
| 4199 }, | |
| 4200 attached: function() { | |
| 4201 if (this.attrForValue) { | |
| 4202 this._inputElement.addEventListener(this._valueChangedEvent, this._boundVa
lueChanged); | |
| 4203 } else { | |
| 4204 this.addEventListener('input', this._onInput); | |
| 4205 } | |
| 4206 if (this._inputElementValue != '') { | |
| 4207 this._handleValueAndAutoValidate(this._inputElement); | |
| 4208 } else { | |
| 4209 this._handleValue(this._inputElement); | |
| 4210 } | |
| 4211 }, | |
| 4212 _onAddonAttached: function(event) { | |
| 4213 if (!this._addons) { | |
| 4214 this._addons = []; | |
| 4215 } | |
| 4216 var target = event.target; | |
| 4217 if (this._addons.indexOf(target) === -1) { | |
| 4218 this._addons.push(target); | |
| 4219 if (this.isAttached) { | |
| 4220 this._handleValue(this._inputElement); | |
| 4221 } | |
| 4222 } | |
| 4223 }, | |
| 4224 _onFocus: function() { | |
| 4225 this._setFocused(true); | |
| 4226 }, | |
| 4227 _onBlur: function() { | |
| 4228 this._setFocused(false); | |
| 4229 this._handleValueAndAutoValidate(this._inputElement); | |
| 4230 }, | |
| 4231 _onInput: function(event) { | |
| 4232 this._handleValueAndAutoValidate(event.target); | |
| 4233 }, | |
| 4234 _onValueChanged: function(event) { | |
| 4235 this._handleValueAndAutoValidate(event.target); | |
| 4236 }, | |
| 4237 _handleValue: function(inputElement) { | |
| 4238 var value = this._inputElementValue; | |
| 4239 if (value || value === 0 || inputElement.type === 'number' && !inputElement.
checkValidity()) { | |
| 4240 this._inputHasContent = true; | |
| 4241 } else { | |
| 4242 this._inputHasContent = false; | |
| 4243 } | |
| 4244 this.updateAddons({ | |
| 4245 inputElement: inputElement, | |
| 4246 value: value, | |
| 4247 invalid: this.invalid | |
| 4248 }); | |
| 4249 }, | |
| 4250 _handleValueAndAutoValidate: function(inputElement) { | |
| 4251 if (this.autoValidate) { | |
| 4252 var valid; | |
| 4253 if (inputElement.validate) { | |
| 4254 valid = inputElement.validate(this._inputElementValue); | |
| 4255 } else { | |
| 4256 valid = inputElement.checkValidity(); | |
| 4257 } | |
| 4258 this.invalid = !valid; | |
| 4259 } | |
| 4260 this._handleValue(inputElement); | |
| 4261 }, | |
| 4262 _onIronInputValidate: function(event) { | |
| 4263 this.invalid = this._inputElement.invalid; | |
| 4264 }, | |
| 4265 _invalidChanged: function() { | |
| 4266 if (this._addons) { | |
| 4267 this.updateAddons({ | |
| 4268 invalid: this.invalid | |
| 4269 }); | |
| 4270 } | |
| 4271 }, | |
| 4272 updateAddons: function(state) { | |
| 4273 for (var addon, index = 0; addon = this._addons[index]; index++) { | |
| 4274 addon.update(state); | |
| 4275 } | |
| 4276 }, | |
| 4277 _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused, i
nvalid, _inputHasContent) { | |
| 4278 var cls = 'input-content'; | |
| 4279 if (!noLabelFloat) { | |
| 4280 var label = this.querySelector('label'); | |
| 4281 if (alwaysFloatLabel || _inputHasContent) { | |
| 4282 cls += ' label-is-floating'; | |
| 4283 this.$.labelAndInputContainer.style.position = 'static'; | |
| 4284 if (invalid) { | |
| 4285 cls += ' is-invalid'; | |
| 4286 } else if (focused) { | |
| 4287 cls += " label-is-highlighted"; | |
| 4288 } | |
| 4289 } else { | |
| 4290 if (label) { | |
| 4291 this.$.labelAndInputContainer.style.position = 'relative'; | |
| 4292 } | |
| 4293 } | |
| 4294 } else { | |
| 4295 if (_inputHasContent) { | |
| 4296 cls += ' label-is-hidden'; | |
| 4297 } | |
| 4298 } | |
| 4299 return cls; | |
| 4300 }, | |
| 4301 _computeUnderlineClass: function(focused, invalid) { | |
| 4302 var cls = 'underline'; | |
| 4303 if (invalid) { | |
| 4304 cls += ' is-invalid'; | |
| 4305 } else if (focused) { | |
| 4306 cls += ' is-highlighted'; | |
| 4307 } | |
| 4308 return cls; | |
| 4309 }, | |
| 4310 _computeAddOnContentClass: function(focused, invalid) { | |
| 4311 var cls = 'add-on-content'; | |
| 4312 if (invalid) { | |
| 4313 cls += ' is-invalid'; | |
| 4314 } else if (focused) { | |
| 4315 cls += ' is-highlighted'; | |
| 4316 } | |
| 4317 return cls; | |
| 4318 } | |
| 4319 }); | |
| 4320 | |
| 4321 Polymer.PaperSpinnerBehavior = { | |
| 4322 listeners: { | |
| 4323 animationend: '__reset', | |
| 4324 webkitAnimationEnd: '__reset' | |
| 4325 }, | |
| 4326 properties: { | |
| 4327 active: { | |
| 4328 type: Boolean, | |
| 4329 value: false, | |
| 4330 reflectToAttribute: true, | |
| 4331 observer: '__activeChanged' | |
| 4332 }, | |
| 4333 alt: { | |
| 4334 type: String, | |
| 4335 value: 'loading', | |
| 4336 observer: '__altChanged' | |
| 4337 }, | |
| 4338 __coolingDown: { | |
| 4339 type: Boolean, | |
| 4340 value: false | |
| 4341 } | |
| 4342 }, | |
| 4343 __computeContainerClasses: function(active, coolingDown) { | |
| 4344 return [ active || coolingDown ? 'active' : '', coolingDown ? 'cooldown' : '
' ].join(' '); | |
| 4345 }, | |
| 4346 __activeChanged: function(active, old) { | |
| 4347 this.__setAriaHidden(!active); | |
| 4348 this.__coolingDown = !active && old; | |
| 4349 }, | |
| 4350 __altChanged: function(alt) { | |
| 4351 if (alt === this.getPropertyInfo('alt').value) { | |
| 4352 this.alt = this.getAttribute('aria-label') || alt; | |
| 4353 } else { | |
| 4354 this.__setAriaHidden(alt === ''); | |
| 4355 this.setAttribute('aria-label', alt); | |
| 4356 } | |
| 4357 }, | |
| 4358 __setAriaHidden: function(hidden) { | |
| 4359 var attr = 'aria-hidden'; | |
| 4360 if (hidden) { | |
| 4361 this.setAttribute(attr, 'true'); | |
| 4362 } else { | |
| 4363 this.removeAttribute(attr); | |
| 4364 } | |
| 4365 }, | |
| 4366 __reset: function() { | |
| 4367 this.active = false; | |
| 4368 this.__coolingDown = false; | |
| 4369 } | |
| 4370 }; | |
| 4371 | |
| 4372 Polymer({ | |
| 4373 is: 'paper-spinner-lite', | |
| 4374 behaviors: [ Polymer.PaperSpinnerBehavior ] | |
| 4375 }); | |
| 4376 | |
| 4377 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 4378 // Use of this source code is governed by a BSD-style license that can be | |
| 4379 // found in the LICENSE file. | |
| 4380 var CrSearchFieldBehavior = { | |
| 4381 properties: { | |
| 4382 label: { | |
| 4383 type: String, | |
| 4384 value: '' | |
| 4385 }, | |
| 4386 clearLabel: { | |
| 4387 type: String, | |
| 4388 value: '' | |
| 4389 }, | |
| 4390 showingSearch: { | |
| 4391 type: Boolean, | |
| 4392 value: false, | |
| 4393 notify: true, | |
| 4394 observer: 'showingSearchChanged_', | |
| 4395 reflectToAttribute: true | |
| 4396 }, | |
| 4397 lastValue_: { | |
| 4398 type: String, | |
| 4399 value: '' | |
| 4400 } | |
| 4401 }, | |
| 4402 getSearchInput: function() {}, | |
| 4403 getValue: function() { | |
| 4404 return this.getSearchInput().value; | |
| 4405 }, | |
| 4406 setValue: function(value) { | |
| 4407 this.getSearchInput().bindValue = value; | |
| 4408 this.onValueChanged_(value); | |
| 4409 }, | |
| 4410 showAndFocus: function() { | |
| 4411 this.showingSearch = true; | |
| 4412 this.focus_(); | |
| 4413 }, | |
| 4414 focus_: function() { | |
| 4415 this.getSearchInput().focus(); | |
| 4416 }, | |
| 4417 onSearchTermSearch: function() { | |
| 4418 this.onValueChanged_(this.getValue()); | |
| 4419 }, | |
| 4420 onValueChanged_: function(newValue) { | |
| 4421 if (newValue == this.lastValue_) return; | |
| 4422 this.fire('search-changed', newValue); | |
| 4423 this.lastValue_ = newValue; | |
| 4424 }, | |
| 4425 onSearchTermKeydown: function(e) { | |
| 4426 if (e.key == 'Escape') this.showingSearch = false; | |
| 4427 }, | |
| 4428 showingSearchChanged_: function() { | |
| 4429 if (this.showingSearch) { | |
| 4430 this.focus_(); | |
| 4431 return; | |
| 4432 } | |
| 4433 this.setValue(''); | |
| 4434 this.getSearchInput().blur(); | |
| 4435 } | |
| 4436 }; | |
| 4437 | |
| 4438 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 4439 // Use of this source code is governed by a BSD-style license that can be | |
| 4440 // found in the LICENSE file. | |
| 4441 Polymer({ | |
| 4442 is: 'cr-toolbar-search-field', | |
| 4443 behaviors: [ CrSearchFieldBehavior ], | |
| 4444 properties: { | |
| 4445 narrow: { | |
| 4446 type: Boolean, | |
| 4447 reflectToAttribute: true | |
| 4448 }, | |
| 4449 label: String, | |
| 4450 clearLabel: String, | |
| 4451 spinnerActive: { | |
| 4452 type: Boolean, | |
| 4453 reflectToAttribute: true | |
| 4454 }, | |
| 4455 hasSearchText_: Boolean | |
| 4456 }, | |
| 4457 listeners: { | |
| 4458 tap: 'showSearch_', | |
| 4459 'searchInput.bind-value-changed': 'onBindValueChanged_' | |
| 4460 }, | |
| 4461 getSearchInput: function() { | |
| 4462 return this.$.searchInput; | |
| 4463 }, | |
| 4464 isSearchFocused: function() { | |
| 4465 return this.$.searchTerm.focused; | |
| 4466 }, | |
| 4467 computeIconTabIndex_: function(narrow) { | |
| 4468 return narrow ? 0 : -1; | |
| 4469 }, | |
| 4470 isSpinnerShown_: function(spinnerActive, showingSearch) { | |
| 4471 return spinnerActive && showingSearch; | |
| 4472 }, | |
| 4473 onInputBlur_: function() { | |
| 4474 if (!this.hasSearchText_) this.showingSearch = false; | |
| 4475 }, | |
| 4476 onBindValueChanged_: function() { | |
| 4477 var newValue = this.$.searchInput.bindValue; | |
| 4478 this.hasSearchText_ = newValue != ''; | |
| 4479 if (newValue != '') this.showingSearch = true; | |
| 4480 }, | |
| 4481 showSearch_: function(e) { | |
| 4482 if (e.target != this.$.clearSearch) this.showingSearch = true; | |
| 4483 }, | |
| 4484 hideSearch_: function(e) { | |
| 4485 this.showingSearch = false; | |
| 4486 e.stopPropagation(); | |
| 4487 } | |
| 4488 }); | |
| 4489 | |
| 4490 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 4491 // Use of this source code is governed by a BSD-style license that can be | |
| 4492 // found in the LICENSE file. | |
| 4493 Polymer({ | |
| 4494 is: 'cr-toolbar', | |
| 4495 properties: { | |
| 4496 pageName: String, | |
| 4497 searchPrompt: String, | |
| 4498 clearLabel: String, | |
| 4499 menuLabel: String, | |
| 4500 spinnerActive: Boolean, | |
| 4501 showMenu: { | |
| 4502 type: Boolean, | |
| 4503 value: false | |
| 4504 }, | |
| 4505 narrow_: { | |
| 4506 type: Boolean, | |
| 4507 reflectToAttribute: true | |
| 4508 }, | |
| 4509 showingSearch_: { | |
| 4510 type: Boolean, | |
| 4511 reflectToAttribute: true | |
| 4512 } | |
| 4513 }, | |
| 4514 getSearchField: function() { | |
| 4515 return this.$.search; | |
| 4516 }, | |
| 4517 onMenuTap_: function(e) { | |
| 4518 this.fire('cr-menu-tap'); | |
| 4519 } | |
| 4520 }); | |
| 4521 | |
| 4522 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 4523 // Use of this source code is governed by a BSD-style license that can be | |
| 4524 // found in the LICENSE file. | |
| 4525 Polymer({ | |
| 4526 is: 'history-toolbar', | |
| 4527 properties: { | |
| 4528 count: { | |
| 4529 type: Number, | |
| 4530 value: 0, | |
| 4531 observer: 'changeToolbarView_' | |
| 4532 }, | |
| 4533 itemsSelected_: { | |
| 4534 type: Boolean, | |
| 4535 value: false, | |
| 4536 reflectToAttribute: true | |
| 4537 }, | |
| 4538 searchTerm: { | |
| 4539 type: String, | |
| 4540 notify: true | |
| 4541 }, | |
| 4542 spinnerActive: { | |
| 4543 type: Boolean, | |
| 4544 value: false | |
| 4545 }, | |
| 4546 hasDrawer: { | |
| 4547 type: Boolean, | |
| 4548 observer: 'hasDrawerChanged_', | |
| 4549 reflectToAttribute: true | |
| 4550 }, | |
| 4551 isGroupedMode: { | |
| 4552 type: Boolean, | |
| 4553 reflectToAttribute: true | |
| 4554 }, | |
| 4555 groupedRange: { | |
| 4556 type: Number, | |
| 4557 value: 0, | |
| 4558 reflectToAttribute: true, | |
| 4559 notify: true | |
| 4560 }, | |
| 4561 queryStartTime: String, | |
| 4562 queryEndTime: String | |
| 4563 }, | |
| 4564 changeToolbarView_: function() { | |
| 4565 this.itemsSelected_ = this.count > 0; | |
| 4566 }, | |
| 4567 setSearchTerm: function(search) { | |
| 4568 if (this.searchTerm == search) return; | |
| 4569 this.searchTerm = search; | |
| 4570 var searchField = this.$['main-toolbar'].getSearchField(); | |
| 4571 searchField.showAndFocus(); | |
| 4572 searchField.setValue(search); | |
| 4573 }, | |
| 4574 onSearchChanged_: function(event) { | |
| 4575 this.searchTerm = event.detail; | |
| 4576 }, | |
| 4577 onClearSelectionTap_: function() { | |
| 4578 this.fire('unselect-all'); | |
| 4579 }, | |
| 4580 onDeleteTap_: function() { | |
| 4581 this.fire('delete-selected'); | |
| 4582 }, | |
| 4583 get searchBar() { | |
| 4584 return this.$['main-toolbar'].getSearchField(); | |
| 4585 }, | |
| 4586 showSearchField: function() { | |
| 4587 this.$['main-toolbar'].getSearchField().showAndFocus(); | |
| 4588 }, | |
| 4589 deletingAllowed_: function() { | |
| 4590 return loadTimeData.getBoolean('allowDeletingHistory'); | |
| 4591 }, | |
| 4592 numberOfItemsSelected_: function(count) { | |
| 4593 return count > 0 ? loadTimeData.getStringF('itemsSelected', count) : ''; | |
| 4594 }, | |
| 4595 getHistoryInterval_: function(queryStartTime, queryEndTime) { | |
| 4596 return loadTimeData.getStringF('historyInterval', queryStartTime, queryEndTi
me); | |
| 4597 }, | |
| 4598 hasDrawerChanged_: function() { | |
| 4599 this.updateStyles(); | |
| 4600 } | |
| 4601 }); | |
| 4602 | |
| 4603 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 4604 // Use of this source code is governed by a BSD-style license that can be | |
| 4605 // found in the LICENSE file. | |
| 4606 Polymer({ | |
| 4607 is: 'cr-dialog', | |
| 4608 "extends": 'dialog', | |
| 4609 created: function() { | |
| 4610 window.addEventListener('popstate', function() { | |
| 4611 if (this.open) this.cancel(); | |
| 4612 }.bind(this)); | |
| 4613 }, | |
| 4614 cancel: function() { | |
| 4615 this.fire('cancel'); | |
| 4616 HTMLDialogElement.prototype.close.call(this, ''); | |
| 4617 }, | |
| 4618 close: function(opt_returnValue) { | |
| 4619 HTMLDialogElement.prototype.close.call(this, 'success'); | |
| 4620 }, | |
| 4621 getCloseButton: function() { | |
| 4622 return this.$.close; | |
| 4623 } | |
| 4624 }); | |
| 4625 | |
| 4626 Polymer.IronFitBehavior = { | |
| 4627 properties: { | |
| 4628 sizingTarget: { | |
| 4629 type: Object, | |
| 4630 value: function() { | |
| 4631 return this; | |
| 4632 } | |
| 4633 }, | |
| 4634 fitInto: { | |
| 4635 type: Object, | |
| 4636 value: window | |
| 4637 }, | |
| 4638 noOverlap: { | |
| 4639 type: Boolean | |
| 4640 }, | |
| 4641 positionTarget: { | |
| 4642 type: Element | |
| 4643 }, | |
| 4644 horizontalAlign: { | |
| 4645 type: String | |
| 4646 }, | |
| 4647 verticalAlign: { | |
| 4648 type: String | |
| 4649 }, | |
| 4650 dynamicAlign: { | |
| 4651 type: Boolean | |
| 4652 }, | |
| 4653 horizontalOffset: { | |
| 4654 type: Number, | |
| 4655 value: 0, | |
| 4656 notify: true | |
| 4657 }, | |
| 4658 verticalOffset: { | |
| 4659 type: Number, | |
| 4660 value: 0, | |
| 4661 notify: true | |
| 4662 }, | |
| 4663 autoFitOnAttach: { | |
| 4664 type: Boolean, | |
| 4665 value: false | |
| 4666 }, | |
| 4667 _fitInfo: { | |
| 4668 type: Object | |
| 4669 } | |
| 4670 }, | |
| 4671 get _fitWidth() { | |
| 4672 var fitWidth; | |
| 4673 if (this.fitInto === window) { | |
| 4674 fitWidth = this.fitInto.innerWidth; | |
| 4675 } else { | |
| 4676 fitWidth = this.fitInto.getBoundingClientRect().width; | |
| 4677 } | |
| 4678 return fitWidth; | |
| 4679 }, | |
| 4680 get _fitHeight() { | |
| 4681 var fitHeight; | |
| 4682 if (this.fitInto === window) { | |
| 4683 fitHeight = this.fitInto.innerHeight; | |
| 4684 } else { | |
| 4685 fitHeight = this.fitInto.getBoundingClientRect().height; | |
| 4686 } | |
| 4687 return fitHeight; | |
| 4688 }, | |
| 4689 get _fitLeft() { | |
| 4690 var fitLeft; | |
| 4691 if (this.fitInto === window) { | |
| 4692 fitLeft = 0; | |
| 4693 } else { | |
| 4694 fitLeft = this.fitInto.getBoundingClientRect().left; | |
| 4695 } | |
| 4696 return fitLeft; | |
| 4697 }, | |
| 4698 get _fitTop() { | |
| 4699 var fitTop; | |
| 4700 if (this.fitInto === window) { | |
| 4701 fitTop = 0; | |
| 4702 } else { | |
| 4703 fitTop = this.fitInto.getBoundingClientRect().top; | |
| 4704 } | |
| 4705 return fitTop; | |
| 4706 }, | |
| 4707 get _defaultPositionTarget() { | |
| 4708 var parent = Polymer.dom(this).parentNode; | |
| 4709 if (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { | |
| 4710 parent = parent.host; | |
| 4711 } | |
| 4712 return parent; | |
| 4713 }, | |
| 4714 get _localeHorizontalAlign() { | |
| 4715 if (this._isRTL) { | |
| 4716 if (this.horizontalAlign === 'right') { | |
| 4717 return 'left'; | |
| 4718 } | |
| 4719 if (this.horizontalAlign === 'left') { | |
| 4720 return 'right'; | |
| 4721 } | |
| 4722 } | |
| 4723 return this.horizontalAlign; | |
| 4724 }, | |
| 4725 attached: function() { | |
| 4726 this._isRTL = window.getComputedStyle(this).direction == 'rtl'; | |
| 4727 this.positionTarget = this.positionTarget || this._defaultPositionTarget; | |
| 4728 if (this.autoFitOnAttach) { | |
| 4729 if (window.getComputedStyle(this).display === 'none') { | |
| 4730 setTimeout(function() { | |
| 4731 this.fit(); | |
| 4732 }.bind(this)); | |
| 4733 } else { | |
| 4734 this.fit(); | |
| 4735 } | |
| 4736 } | |
| 4737 }, | |
| 4738 fit: function() { | |
| 4739 this.position(); | |
| 4740 this.constrain(); | |
| 4741 this.center(); | |
| 4742 }, | |
| 4743 _discoverInfo: function() { | |
| 4744 if (this._fitInfo) { | |
| 4745 return; | |
| 4746 } | |
| 4747 var target = window.getComputedStyle(this); | |
| 4748 var sizer = window.getComputedStyle(this.sizingTarget); | |
| 4749 this._fitInfo = { | |
| 4750 inlineStyle: { | |
| 4751 top: this.style.top || '', | |
| 4752 left: this.style.left || '', | |
| 4753 position: this.style.position || '' | |
| 4754 }, | |
| 4755 sizerInlineStyle: { | |
| 4756 maxWidth: this.sizingTarget.style.maxWidth || '', | |
| 4757 maxHeight: this.sizingTarget.style.maxHeight || '', | |
| 4758 boxSizing: this.sizingTarget.style.boxSizing || '' | |
| 4759 }, | |
| 4760 positionedBy: { | |
| 4761 vertically: target.top !== 'auto' ? 'top' : target.bottom !== 'auto' ? '
bottom' : null, | |
| 4762 horizontally: target.left !== 'auto' ? 'left' : target.right !== 'auto'
? 'right' : null | |
| 4763 }, | |
| 4764 sizedBy: { | |
| 4765 height: sizer.maxHeight !== 'none', | |
| 4766 width: sizer.maxWidth !== 'none', | |
| 4767 minWidth: parseInt(sizer.minWidth, 10) || 0, | |
| 4768 minHeight: parseInt(sizer.minHeight, 10) || 0 | |
| 4769 }, | |
| 4770 margin: { | |
| 4771 top: parseInt(target.marginTop, 10) || 0, | |
| 4772 right: parseInt(target.marginRight, 10) || 0, | |
| 4773 bottom: parseInt(target.marginBottom, 10) || 0, | |
| 4774 left: parseInt(target.marginLeft, 10) || 0 | |
| 4775 } | |
| 4776 }; | |
| 4777 if (this.verticalOffset) { | |
| 4778 this._fitInfo.margin.top = this._fitInfo.margin.bottom = this.verticalOffs
et; | |
| 4779 this._fitInfo.inlineStyle.marginTop = this.style.marginTop || ''; | |
| 4780 this._fitInfo.inlineStyle.marginBottom = this.style.marginBottom || ''; | |
| 4781 this.style.marginTop = this.style.marginBottom = this.verticalOffset + 'px
'; | |
| 4782 } | |
| 4783 if (this.horizontalOffset) { | |
| 4784 this._fitInfo.margin.left = this._fitInfo.margin.right = this.horizontalOf
fset; | |
| 4785 this._fitInfo.inlineStyle.marginLeft = this.style.marginLeft || ''; | |
| 4786 this._fitInfo.inlineStyle.marginRight = this.style.marginRight || ''; | |
| 4787 this.style.marginLeft = this.style.marginRight = this.horizontalOffset + '
px'; | |
| 4788 } | |
| 4789 }, | |
| 4790 resetFit: function() { | |
| 4791 var info = this._fitInfo || {}; | |
| 4792 for (var property in info.sizerInlineStyle) { | |
| 4793 this.sizingTarget.style[property] = info.sizerInlineStyle[property]; | |
| 4794 } | |
| 4795 for (var property in info.inlineStyle) { | |
| 4796 this.style[property] = info.inlineStyle[property]; | |
| 4797 } | |
| 4798 this._fitInfo = null; | |
| 4799 }, | |
| 4800 refit: function() { | |
| 4801 var scrollLeft = this.sizingTarget.scrollLeft; | |
| 4802 var scrollTop = this.sizingTarget.scrollTop; | |
| 4803 this.resetFit(); | |
| 4804 this.fit(); | |
| 4805 this.sizingTarget.scrollLeft = scrollLeft; | |
| 4806 this.sizingTarget.scrollTop = scrollTop; | |
| 4807 }, | |
| 4808 position: function() { | |
| 4809 if (!this.horizontalAlign && !this.verticalAlign) { | |
| 4810 return; | |
| 4811 } | |
| 4812 this._discoverInfo(); | |
| 4813 this.style.position = 'fixed'; | |
| 4814 this.sizingTarget.style.boxSizing = 'border-box'; | |
| 4815 this.style.left = '0px'; | |
| 4816 this.style.top = '0px'; | |
| 4817 var rect = this.getBoundingClientRect(); | |
| 4818 var positionRect = this.__getNormalizedRect(this.positionTarget); | |
| 4819 var fitRect = this.__getNormalizedRect(this.fitInto); | |
| 4820 var margin = this._fitInfo.margin; | |
| 4821 var size = { | |
| 4822 width: rect.width + margin.left + margin.right, | |
| 4823 height: rect.height + margin.top + margin.bottom | |
| 4824 }; | |
| 4825 var position = this.__getPosition(this._localeHorizontalAlign, this.vertical
Align, size, positionRect, fitRect); | |
| 4826 var left = position.left + margin.left; | |
| 4827 var top = position.top + margin.top; | |
| 4828 var right = Math.min(fitRect.right - margin.right, left + rect.width); | |
| 4829 var bottom = Math.min(fitRect.bottom - margin.bottom, top + rect.height); | |
| 4830 var minWidth = this._fitInfo.sizedBy.minWidth; | |
| 4831 var minHeight = this._fitInfo.sizedBy.minHeight; | |
| 4832 if (left < margin.left) { | |
| 4833 left = margin.left; | |
| 4834 if (right - left < minWidth) { | |
| 4835 left = right - minWidth; | |
| 4836 } | |
| 4837 } | |
| 4838 if (top < margin.top) { | |
| 4839 top = margin.top; | |
| 4840 if (bottom - top < minHeight) { | |
| 4841 top = bottom - minHeight; | |
| 4842 } | |
| 4843 } | |
| 4844 this.sizingTarget.style.maxWidth = right - left + 'px'; | |
| 4845 this.sizingTarget.style.maxHeight = bottom - top + 'px'; | |
| 4846 this.style.left = left - rect.left + 'px'; | |
| 4847 this.style.top = top - rect.top + 'px'; | |
| 4848 }, | |
| 4849 constrain: function() { | |
| 4850 if (this.horizontalAlign || this.verticalAlign) { | |
| 4851 return; | |
| 4852 } | |
| 4853 this._discoverInfo(); | |
| 4854 var info = this._fitInfo; | |
| 4855 if (!info.positionedBy.vertically) { | |
| 4856 this.style.position = 'fixed'; | |
| 4857 this.style.top = '0px'; | |
| 4858 } | |
| 4859 if (!info.positionedBy.horizontally) { | |
| 4860 this.style.position = 'fixed'; | |
| 4861 this.style.left = '0px'; | |
| 4862 } | |
| 4863 this.sizingTarget.style.boxSizing = 'border-box'; | |
| 4864 var rect = this.getBoundingClientRect(); | |
| 4865 if (!info.sizedBy.height) { | |
| 4866 this.__sizeDimension(rect, info.positionedBy.vertically, 'top', 'bottom',
'Height'); | |
| 4867 } | |
| 4868 if (!info.sizedBy.width) { | |
| 4869 this.__sizeDimension(rect, info.positionedBy.horizontally, 'left', 'right'
, 'Width'); | |
| 4870 } | |
| 4871 }, | |
| 4872 _sizeDimension: function(rect, positionedBy, start, end, extent) { | |
| 4873 this.__sizeDimension(rect, positionedBy, start, end, extent); | |
| 4874 }, | |
| 4875 __sizeDimension: function(rect, positionedBy, start, end, extent) { | |
| 4876 var info = this._fitInfo; | |
| 4877 var fitRect = this.__getNormalizedRect(this.fitInto); | |
| 4878 var max = extent === 'Width' ? fitRect.width : fitRect.height; | |
| 4879 var flip = positionedBy === end; | |
| 4880 var offset = flip ? max - rect[end] : rect[start]; | |
| 4881 var margin = info.margin[flip ? start : end]; | |
| 4882 var offsetExtent = 'offset' + extent; | |
| 4883 var sizingOffset = this[offsetExtent] - this.sizingTarget[offsetExtent]; | |
| 4884 this.sizingTarget.style['max' + extent] = max - margin - offset - sizingOffs
et + 'px'; | |
| 4885 }, | |
| 4886 center: function() { | |
| 4887 if (this.horizontalAlign || this.verticalAlign) { | |
| 4888 return; | |
| 4889 } | |
| 4890 this._discoverInfo(); | |
| 4891 var positionedBy = this._fitInfo.positionedBy; | |
| 4892 if (positionedBy.vertically && positionedBy.horizontally) { | |
| 4893 return; | |
| 4894 } | |
| 4895 this.style.position = 'fixed'; | |
| 4896 if (!positionedBy.vertically) { | |
| 4897 this.style.top = '0px'; | |
| 4898 } | |
| 4899 if (!positionedBy.horizontally) { | |
| 4900 this.style.left = '0px'; | |
| 4901 } | |
| 4902 var rect = this.getBoundingClientRect(); | |
| 4903 var fitRect = this.__getNormalizedRect(this.fitInto); | |
| 4904 if (!positionedBy.vertically) { | |
| 4905 var top = fitRect.top - rect.top + (fitRect.height - rect.height) / 2; | |
| 4906 this.style.top = top + 'px'; | |
| 4907 } | |
| 4908 if (!positionedBy.horizontally) { | |
| 4909 var left = fitRect.left - rect.left + (fitRect.width - rect.width) / 2; | |
| 4910 this.style.left = left + 'px'; | |
| 4911 } | |
| 4912 }, | |
| 4913 __getNormalizedRect: function(target) { | |
| 4914 if (target === document.documentElement || target === window) { | |
| 4915 return { | |
| 4916 top: 0, | |
| 4917 left: 0, | |
| 4918 width: window.innerWidth, | |
| 4919 height: window.innerHeight, | |
| 4920 right: window.innerWidth, | |
| 4921 bottom: window.innerHeight | |
| 4922 }; | |
| 4923 } | |
| 4924 return target.getBoundingClientRect(); | |
| 4925 }, | |
| 4926 __getCroppedArea: function(position, size, fitRect) { | |
| 4927 var verticalCrop = Math.min(0, position.top) + Math.min(0, fitRect.bottom -
(position.top + size.height)); | |
| 4928 var horizontalCrop = Math.min(0, position.left) + Math.min(0, fitRect.right
- (position.left + size.width)); | |
| 4929 return Math.abs(verticalCrop) * size.width + Math.abs(horizontalCrop) * size
.height; | |
| 4930 }, | |
| 4931 __getPosition: function(hAlign, vAlign, size, positionRect, fitRect) { | |
| 4932 var positions = [ { | |
| 4933 verticalAlign: 'top', | |
| 4934 horizontalAlign: 'left', | |
| 4935 top: positionRect.top, | |
| 4936 left: positionRect.left | |
| 4937 }, { | |
| 4938 verticalAlign: 'top', | |
| 4939 horizontalAlign: 'right', | |
| 4940 top: positionRect.top, | |
| 4941 left: positionRect.right - size.width | |
| 4942 }, { | |
| 4943 verticalAlign: 'bottom', | |
| 4944 horizontalAlign: 'left', | |
| 4945 top: positionRect.bottom - size.height, | |
| 4946 left: positionRect.left | |
| 4947 }, { | |
| 4948 verticalAlign: 'bottom', | |
| 4949 horizontalAlign: 'right', | |
| 4950 top: positionRect.bottom - size.height, | |
| 4951 left: positionRect.right - size.width | |
| 4952 } ]; | |
| 4953 if (this.noOverlap) { | |
| 4954 for (var i = 0, l = positions.length; i < l; i++) { | |
| 4955 var copy = {}; | |
| 4956 for (var key in positions[i]) { | |
| 4957 copy[key] = positions[i][key]; | |
| 4958 } | |
| 4959 positions.push(copy); | |
| 4960 } | |
| 4961 positions[0].top = positions[1].top += positionRect.height; | |
| 4962 positions[2].top = positions[3].top -= positionRect.height; | |
| 4963 positions[4].left = positions[6].left += positionRect.width; | |
| 4964 positions[5].left = positions[7].left -= positionRect.width; | |
| 4965 } | |
| 4966 vAlign = vAlign === 'auto' ? null : vAlign; | |
| 4967 hAlign = hAlign === 'auto' ? null : hAlign; | |
| 4968 var position; | |
| 4969 for (var i = 0; i < positions.length; i++) { | |
| 4970 var pos = positions[i]; | |
| 4971 if (!this.dynamicAlign && !this.noOverlap && pos.verticalAlign === vAlign
&& pos.horizontalAlign === hAlign) { | |
| 4972 position = pos; | |
| 4973 break; | |
| 4974 } | |
| 4975 var alignOk = (!vAlign || pos.verticalAlign === vAlign) && (!hAlign || pos
.horizontalAlign === hAlign); | |
| 4976 if (!this.dynamicAlign && !alignOk) { | |
| 4977 continue; | |
| 4978 } | |
| 4979 position = position || pos; | |
| 4980 pos.croppedArea = this.__getCroppedArea(pos, size, fitRect); | |
| 4981 var diff = pos.croppedArea - position.croppedArea; | |
| 4982 if (diff < 0 || diff === 0 && alignOk) { | |
| 4983 position = pos; | |
| 4984 } | |
| 4985 if (position.croppedArea === 0 && alignOk) { | |
| 4986 break; | |
| 4987 } | |
| 4988 } | |
| 4989 return position; | |
| 4990 } | |
| 4991 }; | |
| 4992 | |
| 4993 (function() { | |
| 4994 'use strict'; | |
| 4995 Polymer({ | |
| 4996 is: 'iron-overlay-backdrop', | |
| 4997 properties: { | |
| 4998 opened: { | |
| 4999 reflectToAttribute: true, | |
| 5000 type: Boolean, | |
| 5001 value: false, | |
| 5002 observer: '_openedChanged' | |
| 5003 } | |
| 5004 }, | |
| 5005 listeners: { | |
| 5006 transitionend: '_onTransitionend' | |
| 5007 }, | |
| 5008 created: function() { | |
| 5009 this.__openedRaf = null; | |
| 5010 }, | |
| 5011 attached: function() { | |
| 5012 this.opened && this._openedChanged(this.opened); | |
| 5013 }, | |
| 5014 prepare: function() { | |
| 5015 if (this.opened && !this.parentNode) { | |
| 5016 Polymer.dom(document.body).appendChild(this); | |
| 5017 } | |
| 5018 }, | |
| 5019 open: function() { | |
| 5020 this.opened = true; | |
| 5021 }, | |
| 5022 close: function() { | |
| 5023 this.opened = false; | |
| 5024 }, | |
| 5025 complete: function() { | |
| 5026 if (!this.opened && this.parentNode === document.body) { | |
| 5027 Polymer.dom(this.parentNode).removeChild(this); | |
| 5028 } | |
| 5029 }, | |
| 5030 _onTransitionend: function(event) { | |
| 5031 if (event && event.target === this) { | |
| 5032 this.complete(); | |
| 5033 } | |
| 5034 }, | |
| 5035 _openedChanged: function(opened) { | |
| 5036 if (opened) { | |
| 5037 this.prepare(); | |
| 5038 } else { | |
| 5039 var cs = window.getComputedStyle(this); | |
| 5040 if (cs.transitionDuration === '0s' || cs.opacity == 0) { | |
| 5041 this.complete(); | |
| 5042 } | |
| 5043 } | |
| 5044 if (!this.isAttached) { | |
| 5045 return; | |
| 5046 } | |
| 5047 if (this.__openedRaf) { | |
| 5048 window.cancelAnimationFrame(this.__openedRaf); | |
| 5049 this.__openedRaf = null; | |
| 5050 } | |
| 5051 this.scrollTop = this.scrollTop; | |
| 5052 this.__openedRaf = window.requestAnimationFrame(function() { | |
| 5053 this.__openedRaf = null; | |
| 5054 this.toggleClass('opened', this.opened); | |
| 5055 }.bind(this)); | |
| 5056 } | |
| 5057 }); | |
| 5058 })(); | |
| 5059 | |
| 5060 Polymer.IronOverlayManagerClass = function() { | |
| 5061 this._overlays = []; | |
| 5062 this._minimumZ = 101; | |
| 5063 this._backdropElement = null; | |
| 5064 Polymer.Gestures.add(document, 'tap', this._onCaptureClick.bind(this)); | |
| 5065 document.addEventListener('focus', this._onCaptureFocus.bind(this), true); | |
| 5066 document.addEventListener('keydown', this._onCaptureKeyDown.bind(this), true); | |
| 5067 }; | |
| 5068 | |
| 5069 Polymer.IronOverlayManagerClass.prototype = { | |
| 5070 constructor: Polymer.IronOverlayManagerClass, | |
| 5071 get backdropElement() { | |
| 5072 if (!this._backdropElement) { | |
| 5073 this._backdropElement = document.createElement('iron-overlay-backdrop'); | |
| 5074 } | |
| 5075 return this._backdropElement; | |
| 5076 }, | |
| 5077 get deepActiveElement() { | |
| 5078 var active = document.activeElement || document.body; | |
| 5079 while (active.root && Polymer.dom(active.root).activeElement) { | |
| 5080 active = Polymer.dom(active.root).activeElement; | |
| 5081 } | |
| 5082 return active; | |
| 5083 }, | |
| 5084 _bringOverlayAtIndexToFront: function(i) { | |
| 5085 var overlay = this._overlays[i]; | |
| 5086 if (!overlay) { | |
| 5087 return; | |
| 5088 } | |
| 5089 var lastI = this._overlays.length - 1; | |
| 5090 var currentOverlay = this._overlays[lastI]; | |
| 5091 if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay))
{ | |
| 5092 lastI--; | |
| 5093 } | |
| 5094 if (i >= lastI) { | |
| 5095 return; | |
| 5096 } | |
| 5097 var minimumZ = Math.max(this.currentOverlayZ(), this._minimumZ); | |
| 5098 if (this._getZ(overlay) <= minimumZ) { | |
| 5099 this._applyOverlayZ(overlay, minimumZ); | |
| 5100 } | |
| 5101 while (i < lastI) { | |
| 5102 this._overlays[i] = this._overlays[i + 1]; | |
| 5103 i++; | |
| 5104 } | |
| 5105 this._overlays[lastI] = overlay; | |
| 5106 }, | |
| 5107 addOrRemoveOverlay: function(overlay) { | |
| 5108 if (overlay.opened) { | |
| 5109 this.addOverlay(overlay); | |
| 5110 } else { | |
| 5111 this.removeOverlay(overlay); | |
| 5112 } | |
| 5113 }, | |
| 5114 addOverlay: function(overlay) { | |
| 5115 var i = this._overlays.indexOf(overlay); | |
| 5116 if (i >= 0) { | |
| 5117 this._bringOverlayAtIndexToFront(i); | |
| 5118 this.trackBackdrop(); | |
| 5119 return; | |
| 5120 } | |
| 5121 var insertionIndex = this._overlays.length; | |
| 5122 var currentOverlay = this._overlays[insertionIndex - 1]; | |
| 5123 var minimumZ = Math.max(this._getZ(currentOverlay), this._minimumZ); | |
| 5124 var newZ = this._getZ(overlay); | |
| 5125 if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay))
{ | |
| 5126 this._applyOverlayZ(currentOverlay, minimumZ); | |
| 5127 insertionIndex--; | |
| 5128 var previousOverlay = this._overlays[insertionIndex - 1]; | |
| 5129 minimumZ = Math.max(this._getZ(previousOverlay), this._minimumZ); | |
| 5130 } | |
| 5131 if (newZ <= minimumZ) { | |
| 5132 this._applyOverlayZ(overlay, minimumZ); | |
| 5133 } | |
| 5134 this._overlays.splice(insertionIndex, 0, overlay); | |
| 5135 this.trackBackdrop(); | |
| 5136 }, | |
| 5137 removeOverlay: function(overlay) { | |
| 5138 var i = this._overlays.indexOf(overlay); | |
| 5139 if (i === -1) { | |
| 5140 return; | |
| 5141 } | |
| 5142 this._overlays.splice(i, 1); | |
| 5143 this.trackBackdrop(); | |
| 5144 }, | |
| 5145 currentOverlay: function() { | |
| 5146 var i = this._overlays.length - 1; | |
| 5147 return this._overlays[i]; | |
| 5148 }, | |
| 5149 currentOverlayZ: function() { | |
| 5150 return this._getZ(this.currentOverlay()); | |
| 5151 }, | |
| 5152 ensureMinimumZ: function(minimumZ) { | |
| 5153 this._minimumZ = Math.max(this._minimumZ, minimumZ); | |
| 5154 }, | |
| 5155 focusOverlay: function() { | |
| 5156 var current = this.currentOverlay(); | |
| 5157 if (current) { | |
| 5158 current._applyFocus(); | |
| 5159 } | |
| 5160 }, | |
| 5161 trackBackdrop: function() { | |
| 5162 var overlay = this._overlayWithBackdrop(); | |
| 5163 if (!overlay && !this._backdropElement) { | |
| 5164 return; | |
| 5165 } | |
| 5166 this.backdropElement.style.zIndex = this._getZ(overlay) - 1; | |
| 5167 this.backdropElement.opened = !!overlay; | |
| 5168 }, | |
| 5169 getBackdrops: function() { | |
| 5170 var backdrops = []; | |
| 5171 for (var i = 0; i < this._overlays.length; i++) { | |
| 5172 if (this._overlays[i].withBackdrop) { | |
| 5173 backdrops.push(this._overlays[i]); | |
| 5174 } | |
| 5175 } | |
| 5176 return backdrops; | |
| 5177 }, | |
| 5178 backdropZ: function() { | |
| 5179 return this._getZ(this._overlayWithBackdrop()) - 1; | |
| 5180 }, | |
| 5181 _overlayWithBackdrop: function() { | |
| 5182 for (var i = 0; i < this._overlays.length; i++) { | |
| 5183 if (this._overlays[i].withBackdrop) { | |
| 5184 return this._overlays[i]; | |
| 5185 } | |
| 5186 } | |
| 5187 }, | |
| 5188 _getZ: function(overlay) { | |
| 5189 var z = this._minimumZ; | |
| 5190 if (overlay) { | |
| 5191 var z1 = Number(overlay.style.zIndex || window.getComputedStyle(overlay).z
Index); | |
| 5192 if (z1 === z1) { | |
| 5193 z = z1; | |
| 5194 } | |
| 5195 } | |
| 5196 return z; | |
| 5197 }, | |
| 5198 _setZ: function(element, z) { | |
| 5199 element.style.zIndex = z; | |
| 5200 }, | |
| 5201 _applyOverlayZ: function(overlay, aboveZ) { | |
| 5202 this._setZ(overlay, aboveZ + 2); | |
| 5203 }, | |
| 5204 _overlayInPath: function(path) { | |
| 5205 path = path || []; | |
| 5206 for (var i = 0; i < path.length; i++) { | |
| 5207 if (path[i]._manager === this) { | |
| 5208 return path[i]; | |
| 5209 } | |
| 5210 } | |
| 5211 }, | |
| 5212 _onCaptureClick: function(event) { | |
| 5213 var overlay = this.currentOverlay(); | |
| 5214 if (overlay && this._overlayInPath(Polymer.dom(event).path) !== overlay) { | |
| 5215 overlay._onCaptureClick(event); | |
| 5216 } | |
| 5217 }, | |
| 5218 _onCaptureFocus: function(event) { | |
| 5219 var overlay = this.currentOverlay(); | |
| 5220 if (overlay) { | |
| 5221 overlay._onCaptureFocus(event); | |
| 5222 } | |
| 5223 }, | |
| 5224 _onCaptureKeyDown: function(event) { | |
| 5225 var overlay = this.currentOverlay(); | |
| 5226 if (overlay) { | |
| 5227 if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(event, 'esc')) { | |
| 5228 overlay._onCaptureEsc(event); | |
| 5229 } else if (Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(event, 't
ab')) { | |
| 5230 overlay._onCaptureTab(event); | |
| 5231 } | |
| 5232 } | |
| 5233 }, | |
| 5234 _shouldBeBehindOverlay: function(overlay1, overlay2) { | |
| 5235 return !overlay1.alwaysOnTop && overlay2.alwaysOnTop; | |
| 5236 } | |
| 5237 }; | |
| 5238 | |
| 5239 Polymer.IronOverlayManager = new Polymer.IronOverlayManagerClass(); | |
| 5240 | |
| 5241 (function() { | |
| 5242 'use strict'; | |
| 5243 Polymer.IronOverlayBehaviorImpl = { | |
| 5244 properties: { | |
| 5245 opened: { | |
| 5246 observer: '_openedChanged', | |
| 5247 type: Boolean, | |
| 5248 value: false, | |
| 5249 notify: true | |
| 5250 }, | |
| 5251 canceled: { | |
| 5252 observer: '_canceledChanged', | |
| 5253 readOnly: true, | |
| 5254 type: Boolean, | |
| 5255 value: false | |
| 5256 }, | |
| 5257 withBackdrop: { | |
| 5258 observer: '_withBackdropChanged', | |
| 5259 type: Boolean | |
| 5260 }, | |
| 5261 noAutoFocus: { | |
| 5262 type: Boolean, | |
| 5263 value: false | |
| 5264 }, | |
| 5265 noCancelOnEscKey: { | |
| 5266 type: Boolean, | |
| 5267 value: false | |
| 5268 }, | |
| 5269 noCancelOnOutsideClick: { | |
| 5270 type: Boolean, | |
| 5271 value: false | |
| 5272 }, | |
| 5273 closingReason: { | |
| 5274 type: Object | |
| 5275 }, | |
| 5276 restoreFocusOnClose: { | |
| 5277 type: Boolean, | |
| 5278 value: false | |
| 5279 }, | |
| 5280 alwaysOnTop: { | |
| 5281 type: Boolean | |
| 5282 }, | |
| 5283 _manager: { | |
| 5284 type: Object, | |
| 5285 value: Polymer.IronOverlayManager | |
| 5286 }, | |
| 5287 _focusedChild: { | |
| 5288 type: Object | |
| 5289 } | |
| 5290 }, | |
| 5291 listeners: { | |
| 5292 'iron-resize': '_onIronResize' | |
| 5293 }, | |
| 5294 get backdropElement() { | |
| 5295 return this._manager.backdropElement; | |
| 5296 }, | |
| 5297 get _focusNode() { | |
| 5298 return this._focusedChild || Polymer.dom(this).querySelector('[autofocus]'
) || this; | |
| 5299 }, | |
| 5300 get _focusableNodes() { | |
| 5301 var FOCUSABLE_WITH_DISABLED = [ 'a[href]', 'area[href]', 'iframe', '[tabin
dex]', '[contentEditable=true]' ]; | |
| 5302 var FOCUSABLE_WITHOUT_DISABLED = [ 'input', 'select', 'textarea', 'button'
]; | |
| 5303 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"])'; | |
| 5304 var focusables = Polymer.dom(this).querySelectorAll(selector); | |
| 5305 if (this.tabIndex >= 0) { | |
| 5306 focusables.splice(0, 0, this); | |
| 5307 } | |
| 5308 return focusables.sort(function(a, b) { | |
| 5309 if (a.tabIndex === b.tabIndex) { | |
| 5310 return 0; | |
| 5311 } | |
| 5312 if (a.tabIndex === 0 || a.tabIndex > b.tabIndex) { | |
| 5313 return 1; | |
| 5314 } | |
| 5315 return -1; | |
| 5316 }); | |
| 5317 }, | |
| 5318 ready: function() { | |
| 5319 this.__isAnimating = false; | |
| 5320 this.__shouldRemoveTabIndex = false; | |
| 5321 this.__firstFocusableNode = this.__lastFocusableNode = null; | |
| 5322 this.__raf = null; | |
| 5323 this.__restoreFocusNode = null; | |
| 5324 this._ensureSetup(); | |
| 5325 }, | |
| 5326 attached: function() { | |
| 5327 if (this.opened) { | |
| 5328 this._openedChanged(this.opened); | |
| 5329 } | |
| 5330 this._observer = Polymer.dom(this).observeNodes(this._onNodesChange); | |
| 5331 }, | |
| 5332 detached: function() { | |
| 5333 Polymer.dom(this).unobserveNodes(this._observer); | |
| 5334 this._observer = null; | |
| 5335 if (this.__raf) { | |
| 5336 window.cancelAnimationFrame(this.__raf); | |
| 5337 this.__raf = null; | |
| 5338 } | |
| 5339 this._manager.removeOverlay(this); | |
| 5340 }, | |
| 5341 toggle: function() { | |
| 5342 this._setCanceled(false); | |
| 5343 this.opened = !this.opened; | |
| 5344 }, | |
| 5345 open: function() { | |
| 5346 this._setCanceled(false); | |
| 5347 this.opened = true; | |
| 5348 }, | |
| 5349 close: function() { | |
| 5350 this._setCanceled(false); | |
| 5351 this.opened = false; | |
| 5352 }, | |
| 5353 cancel: function(event) { | |
| 5354 var cancelEvent = this.fire('iron-overlay-canceled', event, { | |
| 5355 cancelable: true | |
| 5356 }); | |
| 5357 if (cancelEvent.defaultPrevented) { | |
| 5358 return; | |
| 5359 } | |
| 5360 this._setCanceled(true); | |
| 5361 this.opened = false; | |
| 5362 }, | |
| 5363 _ensureSetup: function() { | |
| 5364 if (this._overlaySetup) { | |
| 5365 return; | |
| 5366 } | |
| 5367 this._overlaySetup = true; | |
| 5368 this.style.outline = 'none'; | |
| 5369 this.style.display = 'none'; | |
| 5370 }, | |
| 5371 _openedChanged: function(opened) { | |
| 5372 if (opened) { | |
| 5373 this.removeAttribute('aria-hidden'); | |
| 5374 } else { | |
| 5375 this.setAttribute('aria-hidden', 'true'); | |
| 5376 } | |
| 5377 if (!this.isAttached) { | |
| 5378 return; | |
| 5379 } | |
| 5380 this.__isAnimating = true; | |
| 5381 this.__onNextAnimationFrame(this.__openedChanged); | |
| 5382 }, | |
| 5383 _canceledChanged: function() { | |
| 5384 this.closingReason = this.closingReason || {}; | |
| 5385 this.closingReason.canceled = this.canceled; | |
| 5386 }, | |
| 5387 _withBackdropChanged: function() { | |
| 5388 if (this.withBackdrop && !this.hasAttribute('tabindex')) { | |
| 5389 this.setAttribute('tabindex', '-1'); | |
| 5390 this.__shouldRemoveTabIndex = true; | |
| 5391 } else if (this.__shouldRemoveTabIndex) { | |
| 5392 this.removeAttribute('tabindex'); | |
| 5393 this.__shouldRemoveTabIndex = false; | |
| 5394 } | |
| 5395 if (this.opened && this.isAttached) { | |
| 5396 this._manager.trackBackdrop(); | |
| 5397 } | |
| 5398 }, | |
| 5399 _prepareRenderOpened: function() { | |
| 5400 this.__restoreFocusNode = this._manager.deepActiveElement; | |
| 5401 this._preparePositioning(); | |
| 5402 this.refit(); | |
| 5403 this._finishPositioning(); | |
| 5404 if (this.noAutoFocus && document.activeElement === this._focusNode) { | |
| 5405 this._focusNode.blur(); | |
| 5406 this.__restoreFocusNode.focus(); | |
| 5407 } | |
| 5408 }, | |
| 5409 _renderOpened: function() { | |
| 5410 this._finishRenderOpened(); | |
| 5411 }, | |
| 5412 _renderClosed: function() { | |
| 5413 this._finishRenderClosed(); | |
| 5414 }, | |
| 5415 _finishRenderOpened: function() { | |
| 5416 this.notifyResize(); | |
| 5417 this.__isAnimating = false; | |
| 5418 var focusableNodes = this._focusableNodes; | |
| 5419 this.__firstFocusableNode = focusableNodes[0]; | |
| 5420 this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1]; | |
| 5421 this.fire('iron-overlay-opened'); | |
| 5422 }, | |
| 5423 _finishRenderClosed: function() { | |
| 5424 this.style.display = 'none'; | |
| 5425 this.style.zIndex = ''; | |
| 5426 this.notifyResize(); | |
| 5427 this.__isAnimating = false; | |
| 5428 this.fire('iron-overlay-closed', this.closingReason); | |
| 5429 }, | |
| 5430 _preparePositioning: function() { | |
| 5431 this.style.transition = this.style.webkitTransition = 'none'; | |
| 5432 this.style.transform = this.style.webkitTransform = 'none'; | |
| 5433 this.style.display = ''; | |
| 5434 }, | |
| 5435 _finishPositioning: function() { | |
| 5436 this.style.display = 'none'; | |
| 5437 this.scrollTop = this.scrollTop; | |
| 5438 this.style.transition = this.style.webkitTransition = ''; | |
| 5439 this.style.transform = this.style.webkitTransform = ''; | |
| 5440 this.style.display = ''; | |
| 5441 this.scrollTop = this.scrollTop; | |
| 5442 }, | |
| 5443 _applyFocus: function() { | |
| 5444 if (this.opened) { | |
| 5445 if (!this.noAutoFocus) { | |
| 5446 this._focusNode.focus(); | |
| 5447 } | |
| 5448 } else { | |
| 5449 this._focusNode.blur(); | |
| 5450 this._focusedChild = null; | |
| 5451 if (this.restoreFocusOnClose && this.__restoreFocusNode) { | |
| 5452 this.__restoreFocusNode.focus(); | |
| 5453 } | |
| 5454 this.__restoreFocusNode = null; | |
| 5455 var currentOverlay = this._manager.currentOverlay(); | |
| 5456 if (currentOverlay && this !== currentOverlay) { | |
| 5457 currentOverlay._applyFocus(); | |
| 5458 } | |
| 5459 } | |
| 5460 }, | |
| 5461 _onCaptureClick: function(event) { | |
| 5462 if (!this.noCancelOnOutsideClick) { | |
| 5463 this.cancel(event); | |
| 5464 } | |
| 5465 }, | |
| 5466 _onCaptureFocus: function(event) { | |
| 5467 if (!this.withBackdrop) { | |
| 5468 return; | |
| 5469 } | |
| 5470 var path = Polymer.dom(event).path; | |
| 5471 if (path.indexOf(this) === -1) { | |
| 5472 event.stopPropagation(); | |
| 5473 this._applyFocus(); | |
| 5474 } else { | |
| 5475 this._focusedChild = path[0]; | |
| 5476 } | |
| 5477 }, | |
| 5478 _onCaptureEsc: function(event) { | |
| 5479 if (!this.noCancelOnEscKey) { | |
| 5480 this.cancel(event); | |
| 5481 } | |
| 5482 }, | |
| 5483 _onCaptureTab: function(event) { | |
| 5484 if (!this.withBackdrop) { | |
| 5485 return; | |
| 5486 } | |
| 5487 var shift = event.shiftKey; | |
| 5488 var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusable
Node; | |
| 5489 var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNo
de; | |
| 5490 var shouldWrap = false; | |
| 5491 if (nodeToCheck === nodeToSet) { | |
| 5492 shouldWrap = true; | |
| 5493 } else { | |
| 5494 var focusedNode = this._manager.deepActiveElement; | |
| 5495 shouldWrap = focusedNode === nodeToCheck || focusedNode === this; | |
| 5496 } | |
| 5497 if (shouldWrap) { | |
| 5498 event.preventDefault(); | |
| 5499 this._focusedChild = nodeToSet; | |
| 5500 this._applyFocus(); | |
| 5501 } | |
| 5502 }, | |
| 5503 _onIronResize: function() { | |
| 5504 if (this.opened && !this.__isAnimating) { | |
| 5505 this.__onNextAnimationFrame(this.refit); | |
| 5506 } | |
| 5507 }, | |
| 5508 _onNodesChange: function() { | |
| 5509 if (this.opened && !this.__isAnimating) { | |
| 5510 this.notifyResize(); | |
| 5511 } | |
| 5512 }, | |
| 5513 __openedChanged: function() { | |
| 5514 if (this.opened) { | |
| 5515 this._prepareRenderOpened(); | |
| 5516 this._manager.addOverlay(this); | |
| 5517 this._applyFocus(); | |
| 5518 this._renderOpened(); | |
| 5519 } else { | |
| 5520 this._manager.removeOverlay(this); | |
| 5521 this._applyFocus(); | |
| 5522 this._renderClosed(); | |
| 5523 } | |
| 5524 }, | |
| 5525 __onNextAnimationFrame: function(callback) { | |
| 5526 if (this.__raf) { | |
| 5527 window.cancelAnimationFrame(this.__raf); | |
| 5528 } | |
| 5529 var self = this; | |
| 5530 this.__raf = window.requestAnimationFrame(function nextAnimationFrame() { | |
| 5531 self.__raf = null; | |
| 5532 callback.call(self); | |
| 5533 }); | |
| 5534 } | |
| 5535 }; | |
| 5536 Polymer.IronOverlayBehavior = [ Polymer.IronFitBehavior, Polymer.IronResizable
Behavior, Polymer.IronOverlayBehaviorImpl ]; | |
| 5537 })(); | |
| 5538 | |
| 5539 Polymer.NeonAnimatableBehavior = { | 3343 Polymer.NeonAnimatableBehavior = { |
| 5540 properties: { | 3344 properties: { |
| 5541 animationConfig: { | 3345 animationConfig: { |
| 5542 type: Object | 3346 type: Object |
| 5543 }, | 3347 }, |
| 5544 entryAnimation: { | 3348 entryAnimation: { |
| 5545 observer: '_entryAnimationChanged', | 3349 observer: '_entryAnimationChanged', |
| 5546 type: String | 3350 type: String |
| 5547 }, | 3351 }, |
| 5548 exitAnimation: { | 3352 exitAnimation: { |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6097 if (focusTarget && this.opened && !this.noAutoFocus) { | 3901 if (focusTarget && this.opened && !this.noAutoFocus) { |
| 6098 focusTarget.focus(); | 3902 focusTarget.focus(); |
| 6099 } else { | 3903 } else { |
| 6100 Polymer.IronOverlayBehaviorImpl._applyFocus.apply(this, arguments); | 3904 Polymer.IronOverlayBehaviorImpl._applyFocus.apply(this, arguments); |
| 6101 } | 3905 } |
| 6102 } | 3906 } |
| 6103 }); | 3907 }); |
| 6104 })(); | 3908 })(); |
| 6105 | 3909 |
| 6106 Polymer({ | 3910 Polymer({ |
| 3911 is: 'iron-icon', |
| 3912 properties: { |
| 3913 icon: { |
| 3914 type: String, |
| 3915 observer: '_iconChanged' |
| 3916 }, |
| 3917 theme: { |
| 3918 type: String, |
| 3919 observer: '_updateIcon' |
| 3920 }, |
| 3921 src: { |
| 3922 type: String, |
| 3923 observer: '_srcChanged' |
| 3924 }, |
| 3925 _meta: { |
| 3926 value: Polymer.Base.create('iron-meta', { |
| 3927 type: 'iconset' |
| 3928 }), |
| 3929 observer: '_updateIcon' |
| 3930 } |
| 3931 }, |
| 3932 _DEFAULT_ICONSET: 'icons', |
| 3933 _iconChanged: function(icon) { |
| 3934 var parts = (icon || '').split(':'); |
| 3935 this._iconName = parts.pop(); |
| 3936 this._iconsetName = parts.pop() || this._DEFAULT_ICONSET; |
| 3937 this._updateIcon(); |
| 3938 }, |
| 3939 _srcChanged: function(src) { |
| 3940 this._updateIcon(); |
| 3941 }, |
| 3942 _usesIconset: function() { |
| 3943 return this.icon || !this.src; |
| 3944 }, |
| 3945 _updateIcon: function() { |
| 3946 if (this._usesIconset()) { |
| 3947 if (this._img && this._img.parentNode) { |
| 3948 Polymer.dom(this.root).removeChild(this._img); |
| 3949 } |
| 3950 if (this._iconName === "") { |
| 3951 if (this._iconset) { |
| 3952 this._iconset.removeIcon(this); |
| 3953 } |
| 3954 } else if (this._iconsetName && this._meta) { |
| 3955 this._iconset = this._meta.byKey(this._iconsetName); |
| 3956 if (this._iconset) { |
| 3957 this._iconset.applyIcon(this, this._iconName, this.theme); |
| 3958 this.unlisten(window, 'iron-iconset-added', '_updateIcon'); |
| 3959 } else { |
| 3960 this.listen(window, 'iron-iconset-added', '_updateIcon'); |
| 3961 } |
| 3962 } |
| 3963 } else { |
| 3964 if (this._iconset) { |
| 3965 this._iconset.removeIcon(this); |
| 3966 } |
| 3967 if (!this._img) { |
| 3968 this._img = document.createElement('img'); |
| 3969 this._img.style.width = '100%'; |
| 3970 this._img.style.height = '100%'; |
| 3971 this._img.draggable = false; |
| 3972 } |
| 3973 this._img.src = this.src; |
| 3974 Polymer.dom(this.root).appendChild(this._img); |
| 3975 } |
| 3976 } |
| 3977 }); |
| 3978 |
| 3979 Polymer.IronButtonStateImpl = { |
| 3980 properties: { |
| 3981 pressed: { |
| 3982 type: Boolean, |
| 3983 readOnly: true, |
| 3984 value: false, |
| 3985 reflectToAttribute: true, |
| 3986 observer: '_pressedChanged' |
| 3987 }, |
| 3988 toggles: { |
| 3989 type: Boolean, |
| 3990 value: false, |
| 3991 reflectToAttribute: true |
| 3992 }, |
| 3993 active: { |
| 3994 type: Boolean, |
| 3995 value: false, |
| 3996 notify: true, |
| 3997 reflectToAttribute: true |
| 3998 }, |
| 3999 pointerDown: { |
| 4000 type: Boolean, |
| 4001 readOnly: true, |
| 4002 value: false |
| 4003 }, |
| 4004 receivedFocusFromKeyboard: { |
| 4005 type: Boolean, |
| 4006 readOnly: true |
| 4007 }, |
| 4008 ariaActiveAttribute: { |
| 4009 type: String, |
| 4010 value: 'aria-pressed', |
| 4011 observer: '_ariaActiveAttributeChanged' |
| 4012 } |
| 4013 }, |
| 4014 listeners: { |
| 4015 down: '_downHandler', |
| 4016 up: '_upHandler', |
| 4017 tap: '_tapHandler' |
| 4018 }, |
| 4019 observers: [ '_detectKeyboardFocus(focused)', '_activeChanged(active, ariaActi
veAttribute)' ], |
| 4020 keyBindings: { |
| 4021 'enter:keydown': '_asyncClick', |
| 4022 'space:keydown': '_spaceKeyDownHandler', |
| 4023 'space:keyup': '_spaceKeyUpHandler' |
| 4024 }, |
| 4025 _mouseEventRe: /^mouse/, |
| 4026 _tapHandler: function() { |
| 4027 if (this.toggles) { |
| 4028 this._userActivate(!this.active); |
| 4029 } else { |
| 4030 this.active = false; |
| 4031 } |
| 4032 }, |
| 4033 _detectKeyboardFocus: function(focused) { |
| 4034 this._setReceivedFocusFromKeyboard(!this.pointerDown && focused); |
| 4035 }, |
| 4036 _userActivate: function(active) { |
| 4037 if (this.active !== active) { |
| 4038 this.active = active; |
| 4039 this.fire('change'); |
| 4040 } |
| 4041 }, |
| 4042 _downHandler: function(event) { |
| 4043 this._setPointerDown(true); |
| 4044 this._setPressed(true); |
| 4045 this._setReceivedFocusFromKeyboard(false); |
| 4046 }, |
| 4047 _upHandler: function() { |
| 4048 this._setPointerDown(false); |
| 4049 this._setPressed(false); |
| 4050 }, |
| 4051 _spaceKeyDownHandler: function(event) { |
| 4052 var keyboardEvent = event.detail.keyboardEvent; |
| 4053 var target = Polymer.dom(keyboardEvent).localTarget; |
| 4054 if (this.isLightDescendant(target)) return; |
| 4055 keyboardEvent.preventDefault(); |
| 4056 keyboardEvent.stopImmediatePropagation(); |
| 4057 this._setPressed(true); |
| 4058 }, |
| 4059 _spaceKeyUpHandler: function(event) { |
| 4060 var keyboardEvent = event.detail.keyboardEvent; |
| 4061 var target = Polymer.dom(keyboardEvent).localTarget; |
| 4062 if (this.isLightDescendant(target)) return; |
| 4063 if (this.pressed) { |
| 4064 this._asyncClick(); |
| 4065 } |
| 4066 this._setPressed(false); |
| 4067 }, |
| 4068 _asyncClick: function() { |
| 4069 this.async(function() { |
| 4070 this.click(); |
| 4071 }, 1); |
| 4072 }, |
| 4073 _pressedChanged: function(pressed) { |
| 4074 this._changedButtonState(); |
| 4075 }, |
| 4076 _ariaActiveAttributeChanged: function(value, oldValue) { |
| 4077 if (oldValue && oldValue != value && this.hasAttribute(oldValue)) { |
| 4078 this.removeAttribute(oldValue); |
| 4079 } |
| 4080 }, |
| 4081 _activeChanged: function(active, ariaActiveAttribute) { |
| 4082 if (this.toggles) { |
| 4083 this.setAttribute(this.ariaActiveAttribute, active ? 'true' : 'false'); |
| 4084 } else { |
| 4085 this.removeAttribute(this.ariaActiveAttribute); |
| 4086 } |
| 4087 this._changedButtonState(); |
| 4088 }, |
| 4089 _controlStateChanged: function() { |
| 4090 if (this.disabled) { |
| 4091 this._setPressed(false); |
| 4092 } else { |
| 4093 this._changedButtonState(); |
| 4094 } |
| 4095 }, |
| 4096 _changedButtonState: function() { |
| 4097 if (this._buttonStateChanged) { |
| 4098 this._buttonStateChanged(); |
| 4099 } |
| 4100 } |
| 4101 }; |
| 4102 |
| 4103 Polymer.IronButtonState = [ Polymer.IronA11yKeysBehavior, Polymer.IronButtonStat
eImpl ]; |
| 4104 |
| 4105 (function() { |
| 4106 var Utility = { |
| 4107 distance: function(x1, y1, x2, y2) { |
| 4108 var xDelta = x1 - x2; |
| 4109 var yDelta = y1 - y2; |
| 4110 return Math.sqrt(xDelta * xDelta + yDelta * yDelta); |
| 4111 }, |
| 4112 now: window.performance && window.performance.now ? window.performance.now.b
ind(window.performance) : Date.now |
| 4113 }; |
| 4114 function ElementMetrics(element) { |
| 4115 this.element = element; |
| 4116 this.width = this.boundingRect.width; |
| 4117 this.height = this.boundingRect.height; |
| 4118 this.size = Math.max(this.width, this.height); |
| 4119 } |
| 4120 ElementMetrics.prototype = { |
| 4121 get boundingRect() { |
| 4122 return this.element.getBoundingClientRect(); |
| 4123 }, |
| 4124 furthestCornerDistanceFrom: function(x, y) { |
| 4125 var topLeft = Utility.distance(x, y, 0, 0); |
| 4126 var topRight = Utility.distance(x, y, this.width, 0); |
| 4127 var bottomLeft = Utility.distance(x, y, 0, this.height); |
| 4128 var bottomRight = Utility.distance(x, y, this.width, this.height); |
| 4129 return Math.max(topLeft, topRight, bottomLeft, bottomRight); |
| 4130 } |
| 4131 }; |
| 4132 function Ripple(element) { |
| 4133 this.element = element; |
| 4134 this.color = window.getComputedStyle(element).color; |
| 4135 this.wave = document.createElement('div'); |
| 4136 this.waveContainer = document.createElement('div'); |
| 4137 this.wave.style.backgroundColor = this.color; |
| 4138 this.wave.classList.add('wave'); |
| 4139 this.waveContainer.classList.add('wave-container'); |
| 4140 Polymer.dom(this.waveContainer).appendChild(this.wave); |
| 4141 this.resetInteractionState(); |
| 4142 } |
| 4143 Ripple.MAX_RADIUS = 300; |
| 4144 Ripple.prototype = { |
| 4145 get recenters() { |
| 4146 return this.element.recenters; |
| 4147 }, |
| 4148 get center() { |
| 4149 return this.element.center; |
| 4150 }, |
| 4151 get mouseDownElapsed() { |
| 4152 var elapsed; |
| 4153 if (!this.mouseDownStart) { |
| 4154 return 0; |
| 4155 } |
| 4156 elapsed = Utility.now() - this.mouseDownStart; |
| 4157 if (this.mouseUpStart) { |
| 4158 elapsed -= this.mouseUpElapsed; |
| 4159 } |
| 4160 return elapsed; |
| 4161 }, |
| 4162 get mouseUpElapsed() { |
| 4163 return this.mouseUpStart ? Utility.now() - this.mouseUpStart : 0; |
| 4164 }, |
| 4165 get mouseDownElapsedSeconds() { |
| 4166 return this.mouseDownElapsed / 1e3; |
| 4167 }, |
| 4168 get mouseUpElapsedSeconds() { |
| 4169 return this.mouseUpElapsed / 1e3; |
| 4170 }, |
| 4171 get mouseInteractionSeconds() { |
| 4172 return this.mouseDownElapsedSeconds + this.mouseUpElapsedSeconds; |
| 4173 }, |
| 4174 get initialOpacity() { |
| 4175 return this.element.initialOpacity; |
| 4176 }, |
| 4177 get opacityDecayVelocity() { |
| 4178 return this.element.opacityDecayVelocity; |
| 4179 }, |
| 4180 get radius() { |
| 4181 var width2 = this.containerMetrics.width * this.containerMetrics.width; |
| 4182 var height2 = this.containerMetrics.height * this.containerMetrics.height; |
| 4183 var waveRadius = Math.min(Math.sqrt(width2 + height2), Ripple.MAX_RADIUS)
* 1.1 + 5; |
| 4184 var duration = 1.1 - .2 * (waveRadius / Ripple.MAX_RADIUS); |
| 4185 var timeNow = this.mouseInteractionSeconds / duration; |
| 4186 var size = waveRadius * (1 - Math.pow(80, -timeNow)); |
| 4187 return Math.abs(size); |
| 4188 }, |
| 4189 get opacity() { |
| 4190 if (!this.mouseUpStart) { |
| 4191 return this.initialOpacity; |
| 4192 } |
| 4193 return Math.max(0, this.initialOpacity - this.mouseUpElapsedSeconds * this
.opacityDecayVelocity); |
| 4194 }, |
| 4195 get outerOpacity() { |
| 4196 var outerOpacity = this.mouseUpElapsedSeconds * .3; |
| 4197 var waveOpacity = this.opacity; |
| 4198 return Math.max(0, Math.min(outerOpacity, waveOpacity)); |
| 4199 }, |
| 4200 get isOpacityFullyDecayed() { |
| 4201 return this.opacity < .01 && this.radius >= Math.min(this.maxRadius, Rippl
e.MAX_RADIUS); |
| 4202 }, |
| 4203 get isRestingAtMaxRadius() { |
| 4204 return this.opacity >= this.initialOpacity && this.radius >= Math.min(this
.maxRadius, Ripple.MAX_RADIUS); |
| 4205 }, |
| 4206 get isAnimationComplete() { |
| 4207 return this.mouseUpStart ? this.isOpacityFullyDecayed : this.isRestingAtMa
xRadius; |
| 4208 }, |
| 4209 get translationFraction() { |
| 4210 return Math.min(1, this.radius / this.containerMetrics.size * 2 / Math.sqr
t(2)); |
| 4211 }, |
| 4212 get xNow() { |
| 4213 if (this.xEnd) { |
| 4214 return this.xStart + this.translationFraction * (this.xEnd - this.xStart
); |
| 4215 } |
| 4216 return this.xStart; |
| 4217 }, |
| 4218 get yNow() { |
| 4219 if (this.yEnd) { |
| 4220 return this.yStart + this.translationFraction * (this.yEnd - this.yStart
); |
| 4221 } |
| 4222 return this.yStart; |
| 4223 }, |
| 4224 get isMouseDown() { |
| 4225 return this.mouseDownStart && !this.mouseUpStart; |
| 4226 }, |
| 4227 resetInteractionState: function() { |
| 4228 this.maxRadius = 0; |
| 4229 this.mouseDownStart = 0; |
| 4230 this.mouseUpStart = 0; |
| 4231 this.xStart = 0; |
| 4232 this.yStart = 0; |
| 4233 this.xEnd = 0; |
| 4234 this.yEnd = 0; |
| 4235 this.slideDistance = 0; |
| 4236 this.containerMetrics = new ElementMetrics(this.element); |
| 4237 }, |
| 4238 draw: function() { |
| 4239 var scale; |
| 4240 var translateString; |
| 4241 var dx; |
| 4242 var dy; |
| 4243 this.wave.style.opacity = this.opacity; |
| 4244 scale = this.radius / (this.containerMetrics.size / 2); |
| 4245 dx = this.xNow - this.containerMetrics.width / 2; |
| 4246 dy = this.yNow - this.containerMetrics.height / 2; |
| 4247 this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy
+ 'px)'; |
| 4248 this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + '
px, 0)'; |
| 4249 this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')'; |
| 4250 this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)'; |
| 4251 }, |
| 4252 downAction: function(event) { |
| 4253 var xCenter = this.containerMetrics.width / 2; |
| 4254 var yCenter = this.containerMetrics.height / 2; |
| 4255 this.resetInteractionState(); |
| 4256 this.mouseDownStart = Utility.now(); |
| 4257 if (this.center) { |
| 4258 this.xStart = xCenter; |
| 4259 this.yStart = yCenter; |
| 4260 this.slideDistance = Utility.distance(this.xStart, this.yStart, this.xEn
d, this.yEnd); |
| 4261 } else { |
| 4262 this.xStart = event ? event.detail.x - this.containerMetrics.boundingRec
t.left : this.containerMetrics.width / 2; |
| 4263 this.yStart = event ? event.detail.y - this.containerMetrics.boundingRec
t.top : this.containerMetrics.height / 2; |
| 4264 } |
| 4265 if (this.recenters) { |
| 4266 this.xEnd = xCenter; |
| 4267 this.yEnd = yCenter; |
| 4268 this.slideDistance = Utility.distance(this.xStart, this.yStart, this.xEn
d, this.yEnd); |
| 4269 } |
| 4270 this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom(this.xSt
art, this.yStart); |
| 4271 this.waveContainer.style.top = (this.containerMetrics.height - this.contai
nerMetrics.size) / 2 + 'px'; |
| 4272 this.waveContainer.style.left = (this.containerMetrics.width - this.contai
nerMetrics.size) / 2 + 'px'; |
| 4273 this.waveContainer.style.width = this.containerMetrics.size + 'px'; |
| 4274 this.waveContainer.style.height = this.containerMetrics.size + 'px'; |
| 4275 }, |
| 4276 upAction: function(event) { |
| 4277 if (!this.isMouseDown) { |
| 4278 return; |
| 4279 } |
| 4280 this.mouseUpStart = Utility.now(); |
| 4281 }, |
| 4282 remove: function() { |
| 4283 Polymer.dom(this.waveContainer.parentNode).removeChild(this.waveContainer)
; |
| 4284 } |
| 4285 }; |
| 4286 Polymer({ |
| 4287 is: 'paper-ripple', |
| 4288 behaviors: [ Polymer.IronA11yKeysBehavior ], |
| 4289 properties: { |
| 4290 initialOpacity: { |
| 4291 type: Number, |
| 4292 value: .25 |
| 4293 }, |
| 4294 opacityDecayVelocity: { |
| 4295 type: Number, |
| 4296 value: .8 |
| 4297 }, |
| 4298 recenters: { |
| 4299 type: Boolean, |
| 4300 value: false |
| 4301 }, |
| 4302 center: { |
| 4303 type: Boolean, |
| 4304 value: false |
| 4305 }, |
| 4306 ripples: { |
| 4307 type: Array, |
| 4308 value: function() { |
| 4309 return []; |
| 4310 } |
| 4311 }, |
| 4312 animating: { |
| 4313 type: Boolean, |
| 4314 readOnly: true, |
| 4315 reflectToAttribute: true, |
| 4316 value: false |
| 4317 }, |
| 4318 holdDown: { |
| 4319 type: Boolean, |
| 4320 value: false, |
| 4321 observer: '_holdDownChanged' |
| 4322 }, |
| 4323 noink: { |
| 4324 type: Boolean, |
| 4325 value: false |
| 4326 }, |
| 4327 _animating: { |
| 4328 type: Boolean |
| 4329 }, |
| 4330 _boundAnimate: { |
| 4331 type: Function, |
| 4332 value: function() { |
| 4333 return this.animate.bind(this); |
| 4334 } |
| 4335 } |
| 4336 }, |
| 4337 get target() { |
| 4338 return this.keyEventTarget; |
| 4339 }, |
| 4340 keyBindings: { |
| 4341 'enter:keydown': '_onEnterKeydown', |
| 4342 'space:keydown': '_onSpaceKeydown', |
| 4343 'space:keyup': '_onSpaceKeyup' |
| 4344 }, |
| 4345 attached: function() { |
| 4346 if (this.parentNode.nodeType == 11) { |
| 4347 this.keyEventTarget = Polymer.dom(this).getOwnerRoot().host; |
| 4348 } else { |
| 4349 this.keyEventTarget = this.parentNode; |
| 4350 } |
| 4351 var keyEventTarget = this.keyEventTarget; |
| 4352 this.listen(keyEventTarget, 'up', 'uiUpAction'); |
| 4353 this.listen(keyEventTarget, 'down', 'uiDownAction'); |
| 4354 }, |
| 4355 detached: function() { |
| 4356 this.unlisten(this.keyEventTarget, 'up', 'uiUpAction'); |
| 4357 this.unlisten(this.keyEventTarget, 'down', 'uiDownAction'); |
| 4358 this.keyEventTarget = null; |
| 4359 }, |
| 4360 get shouldKeepAnimating() { |
| 4361 for (var index = 0; index < this.ripples.length; ++index) { |
| 4362 if (!this.ripples[index].isAnimationComplete) { |
| 4363 return true; |
| 4364 } |
| 4365 } |
| 4366 return false; |
| 4367 }, |
| 4368 simulatedRipple: function() { |
| 4369 this.downAction(null); |
| 4370 this.async(function() { |
| 4371 this.upAction(); |
| 4372 }, 1); |
| 4373 }, |
| 4374 uiDownAction: function(event) { |
| 4375 if (!this.noink) { |
| 4376 this.downAction(event); |
| 4377 } |
| 4378 }, |
| 4379 downAction: function(event) { |
| 4380 if (this.holdDown && this.ripples.length > 0) { |
| 4381 return; |
| 4382 } |
| 4383 var ripple = this.addRipple(); |
| 4384 ripple.downAction(event); |
| 4385 if (!this._animating) { |
| 4386 this._animating = true; |
| 4387 this.animate(); |
| 4388 } |
| 4389 }, |
| 4390 uiUpAction: function(event) { |
| 4391 if (!this.noink) { |
| 4392 this.upAction(event); |
| 4393 } |
| 4394 }, |
| 4395 upAction: function(event) { |
| 4396 if (this.holdDown) { |
| 4397 return; |
| 4398 } |
| 4399 this.ripples.forEach(function(ripple) { |
| 4400 ripple.upAction(event); |
| 4401 }); |
| 4402 this._animating = true; |
| 4403 this.animate(); |
| 4404 }, |
| 4405 onAnimationComplete: function() { |
| 4406 this._animating = false; |
| 4407 this.$.background.style.backgroundColor = null; |
| 4408 this.fire('transitionend'); |
| 4409 }, |
| 4410 addRipple: function() { |
| 4411 var ripple = new Ripple(this); |
| 4412 Polymer.dom(this.$.waves).appendChild(ripple.waveContainer); |
| 4413 this.$.background.style.backgroundColor = ripple.color; |
| 4414 this.ripples.push(ripple); |
| 4415 this._setAnimating(true); |
| 4416 return ripple; |
| 4417 }, |
| 4418 removeRipple: function(ripple) { |
| 4419 var rippleIndex = this.ripples.indexOf(ripple); |
| 4420 if (rippleIndex < 0) { |
| 4421 return; |
| 4422 } |
| 4423 this.ripples.splice(rippleIndex, 1); |
| 4424 ripple.remove(); |
| 4425 if (!this.ripples.length) { |
| 4426 this._setAnimating(false); |
| 4427 } |
| 4428 }, |
| 4429 animate: function() { |
| 4430 if (!this._animating) { |
| 4431 return; |
| 4432 } |
| 4433 var index; |
| 4434 var ripple; |
| 4435 for (index = 0; index < this.ripples.length; ++index) { |
| 4436 ripple = this.ripples[index]; |
| 4437 ripple.draw(); |
| 4438 this.$.background.style.opacity = ripple.outerOpacity; |
| 4439 if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) { |
| 4440 this.removeRipple(ripple); |
| 4441 } |
| 4442 } |
| 4443 if (!this.shouldKeepAnimating && this.ripples.length === 0) { |
| 4444 this.onAnimationComplete(); |
| 4445 } else { |
| 4446 window.requestAnimationFrame(this._boundAnimate); |
| 4447 } |
| 4448 }, |
| 4449 _onEnterKeydown: function() { |
| 4450 this.uiDownAction(); |
| 4451 this.async(this.uiUpAction, 1); |
| 4452 }, |
| 4453 _onSpaceKeydown: function() { |
| 4454 this.uiDownAction(); |
| 4455 }, |
| 4456 _onSpaceKeyup: function() { |
| 4457 this.uiUpAction(); |
| 4458 }, |
| 4459 _holdDownChanged: function(newVal, oldVal) { |
| 4460 if (oldVal === undefined) { |
| 4461 return; |
| 4462 } |
| 4463 if (newVal) { |
| 4464 this.downAction(); |
| 4465 } else { |
| 4466 this.upAction(); |
| 4467 } |
| 4468 } |
| 4469 }); |
| 4470 })(); |
| 4471 |
| 4472 Polymer.PaperRippleBehavior = { |
| 4473 properties: { |
| 4474 noink: { |
| 4475 type: Boolean, |
| 4476 observer: '_noinkChanged' |
| 4477 }, |
| 4478 _rippleContainer: { |
| 4479 type: Object |
| 4480 } |
| 4481 }, |
| 4482 _buttonStateChanged: function() { |
| 4483 if (this.focused) { |
| 4484 this.ensureRipple(); |
| 4485 } |
| 4486 }, |
| 4487 _downHandler: function(event) { |
| 4488 Polymer.IronButtonStateImpl._downHandler.call(this, event); |
| 4489 if (this.pressed) { |
| 4490 this.ensureRipple(event); |
| 4491 } |
| 4492 }, |
| 4493 ensureRipple: function(optTriggeringEvent) { |
| 4494 if (!this.hasRipple()) { |
| 4495 this._ripple = this._createRipple(); |
| 4496 this._ripple.noink = this.noink; |
| 4497 var rippleContainer = this._rippleContainer || this.root; |
| 4498 if (rippleContainer) { |
| 4499 Polymer.dom(rippleContainer).appendChild(this._ripple); |
| 4500 } |
| 4501 if (optTriggeringEvent) { |
| 4502 var domContainer = Polymer.dom(this._rippleContainer || this); |
| 4503 var target = Polymer.dom(optTriggeringEvent).rootTarget; |
| 4504 if (domContainer.deepContains(target)) { |
| 4505 this._ripple.uiDownAction(optTriggeringEvent); |
| 4506 } |
| 4507 } |
| 4508 } |
| 4509 }, |
| 4510 getRipple: function() { |
| 4511 this.ensureRipple(); |
| 4512 return this._ripple; |
| 4513 }, |
| 4514 hasRipple: function() { |
| 4515 return Boolean(this._ripple); |
| 4516 }, |
| 4517 _createRipple: function() { |
| 4518 return document.createElement('paper-ripple'); |
| 4519 }, |
| 4520 _noinkChanged: function(noink) { |
| 4521 if (this.hasRipple()) { |
| 4522 this._ripple.noink = noink; |
| 4523 } |
| 4524 } |
| 4525 }; |
| 4526 |
| 4527 Polymer.PaperButtonBehaviorImpl = { |
| 4528 properties: { |
| 4529 elevation: { |
| 4530 type: Number, |
| 4531 reflectToAttribute: true, |
| 4532 readOnly: true |
| 4533 } |
| 4534 }, |
| 4535 observers: [ '_calculateElevation(focused, disabled, active, pressed, received
FocusFromKeyboard)', '_computeKeyboardClass(receivedFocusFromKeyboard)' ], |
| 4536 hostAttributes: { |
| 4537 role: 'button', |
| 4538 tabindex: '0', |
| 4539 animated: true |
| 4540 }, |
| 4541 _calculateElevation: function() { |
| 4542 var e = 1; |
| 4543 if (this.disabled) { |
| 4544 e = 0; |
| 4545 } else if (this.active || this.pressed) { |
| 4546 e = 4; |
| 4547 } else if (this.receivedFocusFromKeyboard) { |
| 4548 e = 3; |
| 4549 } |
| 4550 this._setElevation(e); |
| 4551 }, |
| 4552 _computeKeyboardClass: function(receivedFocusFromKeyboard) { |
| 4553 this.toggleClass('keyboard-focus', receivedFocusFromKeyboard); |
| 4554 }, |
| 4555 _spaceKeyDownHandler: function(event) { |
| 4556 Polymer.IronButtonStateImpl._spaceKeyDownHandler.call(this, event); |
| 4557 if (this.hasRipple() && this.getRipple().ripples.length < 1) { |
| 4558 this._ripple.uiDownAction(); |
| 4559 } |
| 4560 }, |
| 4561 _spaceKeyUpHandler: function(event) { |
| 4562 Polymer.IronButtonStateImpl._spaceKeyUpHandler.call(this, event); |
| 4563 if (this.hasRipple()) { |
| 4564 this._ripple.uiUpAction(); |
| 4565 } |
| 4566 } |
| 4567 }; |
| 4568 |
| 4569 Polymer.PaperButtonBehavior = [ Polymer.IronButtonState, Polymer.IronControlStat
e, Polymer.PaperRippleBehavior, Polymer.PaperButtonBehaviorImpl ]; |
| 4570 |
| 4571 Polymer({ |
| 4572 is: 'paper-button', |
| 4573 behaviors: [ Polymer.PaperButtonBehavior ], |
| 4574 properties: { |
| 4575 raised: { |
| 4576 type: Boolean, |
| 4577 reflectToAttribute: true, |
| 4578 value: false, |
| 4579 observer: '_calculateElevation' |
| 4580 } |
| 4581 }, |
| 4582 _calculateElevation: function() { |
| 4583 if (!this.raised) { |
| 4584 this._setElevation(0); |
| 4585 } else { |
| 4586 Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this); |
| 4587 } |
| 4588 } |
| 4589 }); |
| 4590 |
| 4591 Polymer({ |
| 4592 is: 'paper-icon-button-light', |
| 4593 "extends": 'button', |
| 4594 behaviors: [ Polymer.PaperRippleBehavior ], |
| 4595 listeners: { |
| 4596 down: '_rippleDown', |
| 4597 up: '_rippleUp', |
| 4598 focus: '_rippleDown', |
| 4599 blur: '_rippleUp' |
| 4600 }, |
| 4601 _rippleDown: function() { |
| 4602 this.getRipple().downAction(); |
| 4603 }, |
| 4604 _rippleUp: function() { |
| 4605 this.getRipple().upAction(); |
| 4606 }, |
| 4607 ensureRipple: function(var_args) { |
| 4608 var lastRipple = this._ripple; |
| 4609 Polymer.PaperRippleBehavior.ensureRipple.apply(this, arguments); |
| 4610 if (this._ripple && this._ripple !== lastRipple) { |
| 4611 this._ripple.center = true; |
| 4612 this._ripple.classList.add('circle'); |
| 4613 } |
| 4614 } |
| 4615 }); |
| 4616 |
| 4617 Polymer.PaperInkyFocusBehaviorImpl = { |
| 4618 observers: [ '_focusedChanged(receivedFocusFromKeyboard)' ], |
| 4619 _focusedChanged: function(receivedFocusFromKeyboard) { |
| 4620 if (receivedFocusFromKeyboard) { |
| 4621 this.ensureRipple(); |
| 4622 } |
| 4623 if (this.hasRipple()) { |
| 4624 this._ripple.holdDown = receivedFocusFromKeyboard; |
| 4625 } |
| 4626 }, |
| 4627 _createRipple: function() { |
| 4628 var ripple = Polymer.PaperRippleBehavior._createRipple(); |
| 4629 ripple.id = 'ink'; |
| 4630 ripple.setAttribute('center', ''); |
| 4631 ripple.classList.add('circle'); |
| 4632 return ripple; |
| 4633 } |
| 4634 }; |
| 4635 |
| 4636 Polymer.PaperInkyFocusBehavior = [ Polymer.IronButtonState, Polymer.IronControlS
tate, Polymer.PaperRippleBehavior, Polymer.PaperInkyFocusBehaviorImpl ]; |
| 4637 |
| 4638 Polymer({ |
| 4639 is: 'paper-icon-button', |
| 4640 hostAttributes: { |
| 4641 role: 'button', |
| 4642 tabindex: '0' |
| 4643 }, |
| 4644 behaviors: [ Polymer.PaperInkyFocusBehavior ], |
| 4645 properties: { |
| 4646 src: { |
| 4647 type: String |
| 4648 }, |
| 4649 icon: { |
| 4650 type: String |
| 4651 }, |
| 4652 alt: { |
| 4653 type: String, |
| 4654 observer: "_altChanged" |
| 4655 } |
| 4656 }, |
| 4657 _altChanged: function(newValue, oldValue) { |
| 4658 var label = this.getAttribute('aria-label'); |
| 4659 if (!label || oldValue == label) { |
| 4660 this.setAttribute('aria-label', newValue); |
| 4661 } |
| 4662 } |
| 4663 }); |
| 4664 |
| 4665 Polymer({ |
| 4666 is: 'paper-tab', |
| 4667 behaviors: [ Polymer.IronControlState, Polymer.IronButtonState, Polymer.PaperR
ippleBehavior ], |
| 4668 properties: { |
| 4669 link: { |
| 4670 type: Boolean, |
| 4671 value: false, |
| 4672 reflectToAttribute: true |
| 4673 } |
| 4674 }, |
| 4675 hostAttributes: { |
| 4676 role: 'tab' |
| 4677 }, |
| 4678 listeners: { |
| 4679 down: '_updateNoink', |
| 4680 tap: '_onTap' |
| 4681 }, |
| 4682 attached: function() { |
| 4683 this._updateNoink(); |
| 4684 }, |
| 4685 get _parentNoink() { |
| 4686 var parent = Polymer.dom(this).parentNode; |
| 4687 return !!parent && !!parent.noink; |
| 4688 }, |
| 4689 _updateNoink: function() { |
| 4690 this.noink = !!this.noink || !!this._parentNoink; |
| 4691 }, |
| 4692 _onTap: function(event) { |
| 4693 if (this.link) { |
| 4694 var anchor = this.queryEffectiveChildren('a'); |
| 4695 if (!anchor) { |
| 4696 return; |
| 4697 } |
| 4698 if (event.target === anchor) { |
| 4699 return; |
| 4700 } |
| 4701 anchor.click(); |
| 4702 } |
| 4703 } |
| 4704 }); |
| 4705 |
| 4706 Polymer.IronMultiSelectableBehaviorImpl = { |
| 4707 properties: { |
| 4708 multi: { |
| 4709 type: Boolean, |
| 4710 value: false, |
| 4711 observer: 'multiChanged' |
| 4712 }, |
| 4713 selectedValues: { |
| 4714 type: Array, |
| 4715 notify: true |
| 4716 }, |
| 4717 selectedItems: { |
| 4718 type: Array, |
| 4719 readOnly: true, |
| 4720 notify: true |
| 4721 } |
| 4722 }, |
| 4723 observers: [ '_updateSelected(selectedValues.splices)' ], |
| 4724 select: function(value) { |
| 4725 if (this.multi) { |
| 4726 if (this.selectedValues) { |
| 4727 this._toggleSelected(value); |
| 4728 } else { |
| 4729 this.selectedValues = [ value ]; |
| 4730 } |
| 4731 } else { |
| 4732 this.selected = value; |
| 4733 } |
| 4734 }, |
| 4735 multiChanged: function(multi) { |
| 4736 this._selection.multi = multi; |
| 4737 }, |
| 4738 get _shouldUpdateSelection() { |
| 4739 return this.selected != null || this.selectedValues != null && this.selected
Values.length; |
| 4740 }, |
| 4741 _updateAttrForSelected: function() { |
| 4742 if (!this.multi) { |
| 4743 Polymer.IronSelectableBehavior._updateAttrForSelected.apply(this); |
| 4744 } else if (this._shouldUpdateSelection) { |
| 4745 this.selectedValues = this.selectedItems.map(function(selectedItem) { |
| 4746 return this._indexToValue(this.indexOf(selectedItem)); |
| 4747 }, this).filter(function(unfilteredValue) { |
| 4748 return unfilteredValue != null; |
| 4749 }, this); |
| 4750 } |
| 4751 }, |
| 4752 _updateSelected: function() { |
| 4753 if (this.multi) { |
| 4754 this._selectMulti(this.selectedValues); |
| 4755 } else { |
| 4756 this._selectSelected(this.selected); |
| 4757 } |
| 4758 }, |
| 4759 _selectMulti: function(values) { |
| 4760 if (values) { |
| 4761 var selectedItems = this._valuesToItems(values); |
| 4762 this._selection.clear(selectedItems); |
| 4763 for (var i = 0; i < selectedItems.length; i++) { |
| 4764 this._selection.setItemSelected(selectedItems[i], true); |
| 4765 } |
| 4766 if (this.fallbackSelection && this.items.length && !this._selection.get().
length) { |
| 4767 var fallback = this._valueToItem(this.fallbackSelection); |
| 4768 if (fallback) { |
| 4769 this.selectedValues = [ this.fallbackSelection ]; |
| 4770 } |
| 4771 } |
| 4772 } else { |
| 4773 this._selection.clear(); |
| 4774 } |
| 4775 }, |
| 4776 _selectionChange: function() { |
| 4777 var s = this._selection.get(); |
| 4778 if (this.multi) { |
| 4779 this._setSelectedItems(s); |
| 4780 } else { |
| 4781 this._setSelectedItems([ s ]); |
| 4782 this._setSelectedItem(s); |
| 4783 } |
| 4784 }, |
| 4785 _toggleSelected: function(value) { |
| 4786 var i = this.selectedValues.indexOf(value); |
| 4787 var unselected = i < 0; |
| 4788 if (unselected) { |
| 4789 this.push('selectedValues', value); |
| 4790 } else { |
| 4791 this.splice('selectedValues', i, 1); |
| 4792 } |
| 4793 }, |
| 4794 _valuesToItems: function(values) { |
| 4795 return values == null ? null : values.map(function(value) { |
| 4796 return this._valueToItem(value); |
| 4797 }, this); |
| 4798 } |
| 4799 }; |
| 4800 |
| 4801 Polymer.IronMultiSelectableBehavior = [ Polymer.IronSelectableBehavior, Polymer.
IronMultiSelectableBehaviorImpl ]; |
| 4802 |
| 4803 Polymer.IronMenuBehaviorImpl = { |
| 4804 properties: { |
| 4805 focusedItem: { |
| 4806 observer: '_focusedItemChanged', |
| 4807 readOnly: true, |
| 4808 type: Object |
| 4809 }, |
| 4810 attrForItemTitle: { |
| 4811 type: String |
| 4812 } |
| 4813 }, |
| 4814 hostAttributes: { |
| 4815 role: 'menu', |
| 4816 tabindex: '0' |
| 4817 }, |
| 4818 observers: [ '_updateMultiselectable(multi)' ], |
| 4819 listeners: { |
| 4820 focus: '_onFocus', |
| 4821 keydown: '_onKeydown', |
| 4822 'iron-items-changed': '_onIronItemsChanged' |
| 4823 }, |
| 4824 keyBindings: { |
| 4825 up: '_onUpKey', |
| 4826 down: '_onDownKey', |
| 4827 esc: '_onEscKey', |
| 4828 'shift+tab:keydown': '_onShiftTabDown' |
| 4829 }, |
| 4830 attached: function() { |
| 4831 this._resetTabindices(); |
| 4832 }, |
| 4833 select: function(value) { |
| 4834 if (this._defaultFocusAsync) { |
| 4835 this.cancelAsync(this._defaultFocusAsync); |
| 4836 this._defaultFocusAsync = null; |
| 4837 } |
| 4838 var item = this._valueToItem(value); |
| 4839 if (item && item.hasAttribute('disabled')) return; |
| 4840 this._setFocusedItem(item); |
| 4841 Polymer.IronMultiSelectableBehaviorImpl.select.apply(this, arguments); |
| 4842 }, |
| 4843 _resetTabindices: function() { |
| 4844 var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0]
: this.selectedItem; |
| 4845 this.items.forEach(function(item) { |
| 4846 item.setAttribute('tabindex', item === selectedItem ? '0' : '-1'); |
| 4847 }, this); |
| 4848 }, |
| 4849 _updateMultiselectable: function(multi) { |
| 4850 if (multi) { |
| 4851 this.setAttribute('aria-multiselectable', 'true'); |
| 4852 } else { |
| 4853 this.removeAttribute('aria-multiselectable'); |
| 4854 } |
| 4855 }, |
| 4856 _focusWithKeyboardEvent: function(event) { |
| 4857 for (var i = 0, item; item = this.items[i]; i++) { |
| 4858 var attr = this.attrForItemTitle || 'textContent'; |
| 4859 var title = item[attr] || item.getAttribute(attr); |
| 4860 if (!item.hasAttribute('disabled') && title && title.trim().charAt(0).toLo
werCase() === String.fromCharCode(event.keyCode).toLowerCase()) { |
| 4861 this._setFocusedItem(item); |
| 4862 break; |
| 4863 } |
| 4864 } |
| 4865 }, |
| 4866 _focusPrevious: function() { |
| 4867 var length = this.items.length; |
| 4868 var curFocusIndex = Number(this.indexOf(this.focusedItem)); |
| 4869 for (var i = 1; i < length + 1; i++) { |
| 4870 var item = this.items[(curFocusIndex - i + length) % length]; |
| 4871 if (!item.hasAttribute('disabled')) { |
| 4872 this._setFocusedItem(item); |
| 4873 return; |
| 4874 } |
| 4875 } |
| 4876 }, |
| 4877 _focusNext: function() { |
| 4878 var length = this.items.length; |
| 4879 var curFocusIndex = Number(this.indexOf(this.focusedItem)); |
| 4880 for (var i = 1; i < length + 1; i++) { |
| 4881 var item = this.items[(curFocusIndex + i) % length]; |
| 4882 if (!item.hasAttribute('disabled')) { |
| 4883 this._setFocusedItem(item); |
| 4884 return; |
| 4885 } |
| 4886 } |
| 4887 }, |
| 4888 _applySelection: function(item, isSelected) { |
| 4889 if (isSelected) { |
| 4890 item.setAttribute('aria-selected', 'true'); |
| 4891 } else { |
| 4892 item.removeAttribute('aria-selected'); |
| 4893 } |
| 4894 Polymer.IronSelectableBehavior._applySelection.apply(this, arguments); |
| 4895 }, |
| 4896 _focusedItemChanged: function(focusedItem, old) { |
| 4897 old && old.setAttribute('tabindex', '-1'); |
| 4898 if (focusedItem) { |
| 4899 focusedItem.setAttribute('tabindex', '0'); |
| 4900 focusedItem.focus(); |
| 4901 } |
| 4902 }, |
| 4903 _onIronItemsChanged: function(event) { |
| 4904 if (event.detail.addedNodes.length) { |
| 4905 this._resetTabindices(); |
| 4906 } |
| 4907 }, |
| 4908 _onShiftTabDown: function(event) { |
| 4909 var oldTabIndex = this.getAttribute('tabindex'); |
| 4910 Polymer.IronMenuBehaviorImpl._shiftTabPressed = true; |
| 4911 this._setFocusedItem(null); |
| 4912 this.setAttribute('tabindex', '-1'); |
| 4913 this.async(function() { |
| 4914 this.setAttribute('tabindex', oldTabIndex); |
| 4915 Polymer.IronMenuBehaviorImpl._shiftTabPressed = false; |
| 4916 }, 1); |
| 4917 }, |
| 4918 _onFocus: function(event) { |
| 4919 if (Polymer.IronMenuBehaviorImpl._shiftTabPressed) { |
| 4920 return; |
| 4921 } |
| 4922 var rootTarget = Polymer.dom(event).rootTarget; |
| 4923 if (rootTarget !== this && typeof rootTarget.tabIndex !== "undefined" && !th
is.isLightDescendant(rootTarget)) { |
| 4924 return; |
| 4925 } |
| 4926 this._defaultFocusAsync = this.async(function() { |
| 4927 var selectedItem = this.multi ? this.selectedItems && this.selectedItems[0
] : this.selectedItem; |
| 4928 this._setFocusedItem(null); |
| 4929 if (selectedItem) { |
| 4930 this._setFocusedItem(selectedItem); |
| 4931 } else if (this.items[0]) { |
| 4932 this._focusNext(); |
| 4933 } |
| 4934 }); |
| 4935 }, |
| 4936 _onUpKey: function(event) { |
| 4937 this._focusPrevious(); |
| 4938 event.detail.keyboardEvent.preventDefault(); |
| 4939 }, |
| 4940 _onDownKey: function(event) { |
| 4941 this._focusNext(); |
| 4942 event.detail.keyboardEvent.preventDefault(); |
| 4943 }, |
| 4944 _onEscKey: function(event) { |
| 4945 this.focusedItem.blur(); |
| 4946 }, |
| 4947 _onKeydown: function(event) { |
| 4948 if (!this.keyboardEventMatchesKeys(event, 'up down esc')) { |
| 4949 this._focusWithKeyboardEvent(event); |
| 4950 } |
| 4951 event.stopPropagation(); |
| 4952 }, |
| 4953 _activateHandler: function(event) { |
| 4954 Polymer.IronSelectableBehavior._activateHandler.call(this, event); |
| 4955 event.stopPropagation(); |
| 4956 } |
| 4957 }; |
| 4958 |
| 4959 Polymer.IronMenuBehaviorImpl._shiftTabPressed = false; |
| 4960 |
| 4961 Polymer.IronMenuBehavior = [ Polymer.IronMultiSelectableBehavior, Polymer.IronA1
1yKeysBehavior, Polymer.IronMenuBehaviorImpl ]; |
| 4962 |
| 4963 Polymer.IronMenubarBehaviorImpl = { |
| 4964 hostAttributes: { |
| 4965 role: 'menubar' |
| 4966 }, |
| 4967 keyBindings: { |
| 4968 left: '_onLeftKey', |
| 4969 right: '_onRightKey' |
| 4970 }, |
| 4971 _onUpKey: function(event) { |
| 4972 this.focusedItem.click(); |
| 4973 event.detail.keyboardEvent.preventDefault(); |
| 4974 }, |
| 4975 _onDownKey: function(event) { |
| 4976 this.focusedItem.click(); |
| 4977 event.detail.keyboardEvent.preventDefault(); |
| 4978 }, |
| 4979 get _isRTL() { |
| 4980 return window.getComputedStyle(this)['direction'] === 'rtl'; |
| 4981 }, |
| 4982 _onLeftKey: function(event) { |
| 4983 if (this._isRTL) { |
| 4984 this._focusNext(); |
| 4985 } else { |
| 4986 this._focusPrevious(); |
| 4987 } |
| 4988 event.detail.keyboardEvent.preventDefault(); |
| 4989 }, |
| 4990 _onRightKey: function(event) { |
| 4991 if (this._isRTL) { |
| 4992 this._focusPrevious(); |
| 4993 } else { |
| 4994 this._focusNext(); |
| 4995 } |
| 4996 event.detail.keyboardEvent.preventDefault(); |
| 4997 }, |
| 4998 _onKeydown: function(event) { |
| 4999 if (this.keyboardEventMatchesKeys(event, 'up down left right esc')) { |
| 5000 return; |
| 5001 } |
| 5002 this._focusWithKeyboardEvent(event); |
| 5003 } |
| 5004 }; |
| 5005 |
| 5006 Polymer.IronMenubarBehavior = [ Polymer.IronMenuBehavior, Polymer.IronMenubarBeh
aviorImpl ]; |
| 5007 |
| 5008 Polymer({ |
| 5009 is: 'iron-iconset-svg', |
| 5010 properties: { |
| 5011 name: { |
| 5012 type: String, |
| 5013 observer: '_nameChanged' |
| 5014 }, |
| 5015 size: { |
| 5016 type: Number, |
| 5017 value: 24 |
| 5018 } |
| 5019 }, |
| 5020 attached: function() { |
| 5021 this.style.display = 'none'; |
| 5022 }, |
| 5023 getIconNames: function() { |
| 5024 this._icons = this._createIconMap(); |
| 5025 return Object.keys(this._icons).map(function(n) { |
| 5026 return this.name + ':' + n; |
| 5027 }, this); |
| 5028 }, |
| 5029 applyIcon: function(element, iconName) { |
| 5030 element = element.root || element; |
| 5031 this.removeIcon(element); |
| 5032 var svg = this._cloneIcon(iconName); |
| 5033 if (svg) { |
| 5034 var pde = Polymer.dom(element); |
| 5035 pde.insertBefore(svg, pde.childNodes[0]); |
| 5036 return element._svgIcon = svg; |
| 5037 } |
| 5038 return null; |
| 5039 }, |
| 5040 removeIcon: function(element) { |
| 5041 if (element._svgIcon) { |
| 5042 Polymer.dom(element).removeChild(element._svgIcon); |
| 5043 element._svgIcon = null; |
| 5044 } |
| 5045 }, |
| 5046 _nameChanged: function() { |
| 5047 new Polymer.IronMeta({ |
| 5048 type: 'iconset', |
| 5049 key: this.name, |
| 5050 value: this |
| 5051 }); |
| 5052 this.async(function() { |
| 5053 this.fire('iron-iconset-added', this, { |
| 5054 node: window |
| 5055 }); |
| 5056 }); |
| 5057 }, |
| 5058 _createIconMap: function() { |
| 5059 var icons = Object.create(null); |
| 5060 Polymer.dom(this).querySelectorAll('[id]').forEach(function(icon) { |
| 5061 icons[icon.id] = icon; |
| 5062 }); |
| 5063 return icons; |
| 5064 }, |
| 5065 _cloneIcon: function(id) { |
| 5066 this._icons = this._icons || this._createIconMap(); |
| 5067 return this._prepareSvgClone(this._icons[id], this.size); |
| 5068 }, |
| 5069 _prepareSvgClone: function(sourceSvg, size) { |
| 5070 if (sourceSvg) { |
| 5071 var content = sourceSvg.cloneNode(true), svg = document.createElementNS('h
ttp://www.w3.org/2000/svg', 'svg'), viewBox = content.getAttribute('viewBox') ||
'0 0 ' + size + ' ' + size; |
| 5072 svg.setAttribute('viewBox', viewBox); |
| 5073 svg.setAttribute('preserveAspectRatio', 'xMidYMid meet'); |
| 5074 svg.style.cssText = 'pointer-events: none; display: block; width: 100%; he
ight: 100%;'; |
| 5075 svg.appendChild(content).removeAttribute('id'); |
| 5076 return svg; |
| 5077 } |
| 5078 return null; |
| 5079 } |
| 5080 }); |
| 5081 |
| 5082 Polymer({ |
| 5083 is: 'paper-tabs', |
| 5084 behaviors: [ Polymer.IronResizableBehavior, Polymer.IronMenubarBehavior ], |
| 5085 properties: { |
| 5086 noink: { |
| 5087 type: Boolean, |
| 5088 value: false, |
| 5089 observer: '_noinkChanged' |
| 5090 }, |
| 5091 noBar: { |
| 5092 type: Boolean, |
| 5093 value: false |
| 5094 }, |
| 5095 noSlide: { |
| 5096 type: Boolean, |
| 5097 value: false |
| 5098 }, |
| 5099 scrollable: { |
| 5100 type: Boolean, |
| 5101 value: false |
| 5102 }, |
| 5103 fitContainer: { |
| 5104 type: Boolean, |
| 5105 value: false |
| 5106 }, |
| 5107 disableDrag: { |
| 5108 type: Boolean, |
| 5109 value: false |
| 5110 }, |
| 5111 hideScrollButtons: { |
| 5112 type: Boolean, |
| 5113 value: false |
| 5114 }, |
| 5115 alignBottom: { |
| 5116 type: Boolean, |
| 5117 value: false |
| 5118 }, |
| 5119 selectable: { |
| 5120 type: String, |
| 5121 value: 'paper-tab' |
| 5122 }, |
| 5123 autoselect: { |
| 5124 type: Boolean, |
| 5125 value: false |
| 5126 }, |
| 5127 autoselectDelay: { |
| 5128 type: Number, |
| 5129 value: 0 |
| 5130 }, |
| 5131 _step: { |
| 5132 type: Number, |
| 5133 value: 10 |
| 5134 }, |
| 5135 _holdDelay: { |
| 5136 type: Number, |
| 5137 value: 1 |
| 5138 }, |
| 5139 _leftHidden: { |
| 5140 type: Boolean, |
| 5141 value: false |
| 5142 }, |
| 5143 _rightHidden: { |
| 5144 type: Boolean, |
| 5145 value: false |
| 5146 }, |
| 5147 _previousTab: { |
| 5148 type: Object |
| 5149 } |
| 5150 }, |
| 5151 hostAttributes: { |
| 5152 role: 'tablist' |
| 5153 }, |
| 5154 listeners: { |
| 5155 'iron-resize': '_onTabSizingChanged', |
| 5156 'iron-items-changed': '_onTabSizingChanged', |
| 5157 'iron-select': '_onIronSelect', |
| 5158 'iron-deselect': '_onIronDeselect' |
| 5159 }, |
| 5160 keyBindings: { |
| 5161 'left:keyup right:keyup': '_onArrowKeyup' |
| 5162 }, |
| 5163 created: function() { |
| 5164 this._holdJob = null; |
| 5165 this._pendingActivationItem = undefined; |
| 5166 this._pendingActivationTimeout = undefined; |
| 5167 this._bindDelayedActivationHandler = this._delayedActivationHandler.bind(thi
s); |
| 5168 this.addEventListener('blur', this._onBlurCapture.bind(this), true); |
| 5169 }, |
| 5170 ready: function() { |
| 5171 this.setScrollDirection('y', this.$.tabsContainer); |
| 5172 }, |
| 5173 detached: function() { |
| 5174 this._cancelPendingActivation(); |
| 5175 }, |
| 5176 _noinkChanged: function(noink) { |
| 5177 var childTabs = Polymer.dom(this).querySelectorAll('paper-tab'); |
| 5178 childTabs.forEach(noink ? this._setNoinkAttribute : this._removeNoinkAttribu
te); |
| 5179 }, |
| 5180 _setNoinkAttribute: function(element) { |
| 5181 element.setAttribute('noink', ''); |
| 5182 }, |
| 5183 _removeNoinkAttribute: function(element) { |
| 5184 element.removeAttribute('noink'); |
| 5185 }, |
| 5186 _computeScrollButtonClass: function(hideThisButton, scrollable, hideScrollButt
ons) { |
| 5187 if (!scrollable || hideScrollButtons) { |
| 5188 return 'hidden'; |
| 5189 } |
| 5190 if (hideThisButton) { |
| 5191 return 'not-visible'; |
| 5192 } |
| 5193 return ''; |
| 5194 }, |
| 5195 _computeTabsContentClass: function(scrollable, fitContainer) { |
| 5196 return scrollable ? 'scrollable' + (fitContainer ? ' fit-container' : '') :
' fit-container'; |
| 5197 }, |
| 5198 _computeSelectionBarClass: function(noBar, alignBottom) { |
| 5199 if (noBar) { |
| 5200 return 'hidden'; |
| 5201 } else if (alignBottom) { |
| 5202 return 'align-bottom'; |
| 5203 } |
| 5204 return ''; |
| 5205 }, |
| 5206 _onTabSizingChanged: function() { |
| 5207 this.debounce('_onTabSizingChanged', function() { |
| 5208 this._scroll(); |
| 5209 this._tabChanged(this.selectedItem); |
| 5210 }, 10); |
| 5211 }, |
| 5212 _onIronSelect: function(event) { |
| 5213 this._tabChanged(event.detail.item, this._previousTab); |
| 5214 this._previousTab = event.detail.item; |
| 5215 this.cancelDebouncer('tab-changed'); |
| 5216 }, |
| 5217 _onIronDeselect: function(event) { |
| 5218 this.debounce('tab-changed', function() { |
| 5219 this._tabChanged(null, this._previousTab); |
| 5220 this._previousTab = null; |
| 5221 }, 1); |
| 5222 }, |
| 5223 _activateHandler: function() { |
| 5224 this._cancelPendingActivation(); |
| 5225 Polymer.IronMenuBehaviorImpl._activateHandler.apply(this, arguments); |
| 5226 }, |
| 5227 _scheduleActivation: function(item, delay) { |
| 5228 this._pendingActivationItem = item; |
| 5229 this._pendingActivationTimeout = this.async(this._bindDelayedActivationHandl
er, delay); |
| 5230 }, |
| 5231 _delayedActivationHandler: function() { |
| 5232 var item = this._pendingActivationItem; |
| 5233 this._pendingActivationItem = undefined; |
| 5234 this._pendingActivationTimeout = undefined; |
| 5235 item.fire(this.activateEvent, null, { |
| 5236 bubbles: true, |
| 5237 cancelable: true |
| 5238 }); |
| 5239 }, |
| 5240 _cancelPendingActivation: function() { |
| 5241 if (this._pendingActivationTimeout !== undefined) { |
| 5242 this.cancelAsync(this._pendingActivationTimeout); |
| 5243 this._pendingActivationItem = undefined; |
| 5244 this._pendingActivationTimeout = undefined; |
| 5245 } |
| 5246 }, |
| 5247 _onArrowKeyup: function(event) { |
| 5248 if (this.autoselect) { |
| 5249 this._scheduleActivation(this.focusedItem, this.autoselectDelay); |
| 5250 } |
| 5251 }, |
| 5252 _onBlurCapture: function(event) { |
| 5253 if (event.target === this._pendingActivationItem) { |
| 5254 this._cancelPendingActivation(); |
| 5255 } |
| 5256 }, |
| 5257 get _tabContainerScrollSize() { |
| 5258 return Math.max(0, this.$.tabsContainer.scrollWidth - this.$.tabsContainer.o
ffsetWidth); |
| 5259 }, |
| 5260 _scroll: function(e, detail) { |
| 5261 if (!this.scrollable) { |
| 5262 return; |
| 5263 } |
| 5264 var ddx = detail && -detail.ddx || 0; |
| 5265 this._affectScroll(ddx); |
| 5266 }, |
| 5267 _down: function(e) { |
| 5268 this.async(function() { |
| 5269 if (this._defaultFocusAsync) { |
| 5270 this.cancelAsync(this._defaultFocusAsync); |
| 5271 this._defaultFocusAsync = null; |
| 5272 } |
| 5273 }, 1); |
| 5274 }, |
| 5275 _affectScroll: function(dx) { |
| 5276 this.$.tabsContainer.scrollLeft += dx; |
| 5277 var scrollLeft = this.$.tabsContainer.scrollLeft; |
| 5278 this._leftHidden = scrollLeft === 0; |
| 5279 this._rightHidden = scrollLeft === this._tabContainerScrollSize; |
| 5280 }, |
| 5281 _onLeftScrollButtonDown: function() { |
| 5282 this._scrollToLeft(); |
| 5283 this._holdJob = setInterval(this._scrollToLeft.bind(this), this._holdDelay); |
| 5284 }, |
| 5285 _onRightScrollButtonDown: function() { |
| 5286 this._scrollToRight(); |
| 5287 this._holdJob = setInterval(this._scrollToRight.bind(this), this._holdDelay)
; |
| 5288 }, |
| 5289 _onScrollButtonUp: function() { |
| 5290 clearInterval(this._holdJob); |
| 5291 this._holdJob = null; |
| 5292 }, |
| 5293 _scrollToLeft: function() { |
| 5294 this._affectScroll(-this._step); |
| 5295 }, |
| 5296 _scrollToRight: function() { |
| 5297 this._affectScroll(this._step); |
| 5298 }, |
| 5299 _tabChanged: function(tab, old) { |
| 5300 if (!tab) { |
| 5301 this.$.selectionBar.classList.remove('expand'); |
| 5302 this.$.selectionBar.classList.remove('contract'); |
| 5303 this._positionBar(0, 0); |
| 5304 return; |
| 5305 } |
| 5306 var r = this.$.tabsContent.getBoundingClientRect(); |
| 5307 var w = r.width; |
| 5308 var tabRect = tab.getBoundingClientRect(); |
| 5309 var tabOffsetLeft = tabRect.left - r.left; |
| 5310 this._pos = { |
| 5311 width: this._calcPercent(tabRect.width, w), |
| 5312 left: this._calcPercent(tabOffsetLeft, w) |
| 5313 }; |
| 5314 if (this.noSlide || old == null) { |
| 5315 this.$.selectionBar.classList.remove('expand'); |
| 5316 this.$.selectionBar.classList.remove('contract'); |
| 5317 this._positionBar(this._pos.width, this._pos.left); |
| 5318 return; |
| 5319 } |
| 5320 var oldRect = old.getBoundingClientRect(); |
| 5321 var oldIndex = this.items.indexOf(old); |
| 5322 var index = this.items.indexOf(tab); |
| 5323 var m = 5; |
| 5324 this.$.selectionBar.classList.add('expand'); |
| 5325 var moveRight = oldIndex < index; |
| 5326 var isRTL = this._isRTL; |
| 5327 if (isRTL) { |
| 5328 moveRight = !moveRight; |
| 5329 } |
| 5330 if (moveRight) { |
| 5331 this._positionBar(this._calcPercent(tabRect.left + tabRect.width - oldRect
.left, w) - m, this._left); |
| 5332 } else { |
| 5333 this._positionBar(this._calcPercent(oldRect.left + oldRect.width - tabRect
.left, w) - m, this._calcPercent(tabOffsetLeft, w) + m); |
| 5334 } |
| 5335 if (this.scrollable) { |
| 5336 this._scrollToSelectedIfNeeded(tabRect.width, tabOffsetLeft); |
| 5337 } |
| 5338 }, |
| 5339 _scrollToSelectedIfNeeded: function(tabWidth, tabOffsetLeft) { |
| 5340 var l = tabOffsetLeft - this.$.tabsContainer.scrollLeft; |
| 5341 if (l < 0) { |
| 5342 this.$.tabsContainer.scrollLeft += l; |
| 5343 } else { |
| 5344 l += tabWidth - this.$.tabsContainer.offsetWidth; |
| 5345 if (l > 0) { |
| 5346 this.$.tabsContainer.scrollLeft += l; |
| 5347 } |
| 5348 } |
| 5349 }, |
| 5350 _calcPercent: function(w, w0) { |
| 5351 return 100 * w / w0; |
| 5352 }, |
| 5353 _positionBar: function(width, left) { |
| 5354 width = width || 0; |
| 5355 left = left || 0; |
| 5356 this._width = width; |
| 5357 this._left = left; |
| 5358 this.transform('translateX(' + left + '%) scaleX(' + width / 100 + ')', this
.$.selectionBar); |
| 5359 }, |
| 5360 _onBarTransitionEnd: function(e) { |
| 5361 var cl = this.$.selectionBar.classList; |
| 5362 if (cl.contains('expand')) { |
| 5363 cl.remove('expand'); |
| 5364 cl.add('contract'); |
| 5365 this._positionBar(this._pos.width, this._pos.left); |
| 5366 } else if (cl.contains('contract')) { |
| 5367 cl.remove('contract'); |
| 5368 } |
| 5369 } |
| 5370 }); |
| 5371 |
| 5372 (function() { |
| 5373 'use strict'; |
| 5374 Polymer.IronA11yAnnouncer = Polymer({ |
| 5375 is: 'iron-a11y-announcer', |
| 5376 properties: { |
| 5377 mode: { |
| 5378 type: String, |
| 5379 value: 'polite' |
| 5380 }, |
| 5381 _text: { |
| 5382 type: String, |
| 5383 value: '' |
| 5384 } |
| 5385 }, |
| 5386 created: function() { |
| 5387 if (!Polymer.IronA11yAnnouncer.instance) { |
| 5388 Polymer.IronA11yAnnouncer.instance = this; |
| 5389 } |
| 5390 document.body.addEventListener('iron-announce', this._onIronAnnounce.bind(
this)); |
| 5391 }, |
| 5392 announce: function(text) { |
| 5393 this._text = ''; |
| 5394 this.async(function() { |
| 5395 this._text = text; |
| 5396 }, 100); |
| 5397 }, |
| 5398 _onIronAnnounce: function(event) { |
| 5399 if (event.detail && event.detail.text) { |
| 5400 this.announce(event.detail.text); |
| 5401 } |
| 5402 } |
| 5403 }); |
| 5404 Polymer.IronA11yAnnouncer.instance = null; |
| 5405 Polymer.IronA11yAnnouncer.requestAvailability = function() { |
| 5406 if (!Polymer.IronA11yAnnouncer.instance) { |
| 5407 Polymer.IronA11yAnnouncer.instance = document.createElement('iron-a11y-ann
ouncer'); |
| 5408 } |
| 5409 document.body.appendChild(Polymer.IronA11yAnnouncer.instance); |
| 5410 }; |
| 5411 })(); |
| 5412 |
| 5413 Polymer.IronValidatableBehaviorMeta = null; |
| 5414 |
| 5415 Polymer.IronValidatableBehavior = { |
| 5416 properties: { |
| 5417 validator: { |
| 5418 type: String |
| 5419 }, |
| 5420 invalid: { |
| 5421 notify: true, |
| 5422 reflectToAttribute: true, |
| 5423 type: Boolean, |
| 5424 value: false |
| 5425 }, |
| 5426 _validatorMeta: { |
| 5427 type: Object |
| 5428 }, |
| 5429 validatorType: { |
| 5430 type: String, |
| 5431 value: 'validator' |
| 5432 }, |
| 5433 _validator: { |
| 5434 type: Object, |
| 5435 computed: '__computeValidator(validator)' |
| 5436 } |
| 5437 }, |
| 5438 observers: [ '_invalidChanged(invalid)' ], |
| 5439 registered: function() { |
| 5440 Polymer.IronValidatableBehaviorMeta = new Polymer.IronMeta({ |
| 5441 type: 'validator' |
| 5442 }); |
| 5443 }, |
| 5444 _invalidChanged: function() { |
| 5445 if (this.invalid) { |
| 5446 this.setAttribute('aria-invalid', 'true'); |
| 5447 } else { |
| 5448 this.removeAttribute('aria-invalid'); |
| 5449 } |
| 5450 }, |
| 5451 hasValidator: function() { |
| 5452 return this._validator != null; |
| 5453 }, |
| 5454 validate: function(value) { |
| 5455 this.invalid = !this._getValidity(value); |
| 5456 return !this.invalid; |
| 5457 }, |
| 5458 _getValidity: function(value) { |
| 5459 if (this.hasValidator()) { |
| 5460 return this._validator.validate(value); |
| 5461 } |
| 5462 return true; |
| 5463 }, |
| 5464 __computeValidator: function() { |
| 5465 return Polymer.IronValidatableBehaviorMeta && Polymer.IronValidatableBehavio
rMeta.byKey(this.validator); |
| 5466 } |
| 5467 }; |
| 5468 |
| 5469 Polymer({ |
| 5470 is: 'iron-input', |
| 5471 "extends": 'input', |
| 5472 behaviors: [ Polymer.IronValidatableBehavior ], |
| 5473 properties: { |
| 5474 bindValue: { |
| 5475 observer: '_bindValueChanged', |
| 5476 type: String |
| 5477 }, |
| 5478 preventInvalidInput: { |
| 5479 type: Boolean |
| 5480 }, |
| 5481 allowedPattern: { |
| 5482 type: String, |
| 5483 observer: "_allowedPatternChanged" |
| 5484 }, |
| 5485 _previousValidInput: { |
| 5486 type: String, |
| 5487 value: '' |
| 5488 }, |
| 5489 _patternAlreadyChecked: { |
| 5490 type: Boolean, |
| 5491 value: false |
| 5492 } |
| 5493 }, |
| 5494 listeners: { |
| 5495 input: '_onInput', |
| 5496 keypress: '_onKeypress' |
| 5497 }, |
| 5498 registered: function() { |
| 5499 if (!this._canDispatchEventOnDisabled()) { |
| 5500 this._origDispatchEvent = this.dispatchEvent; |
| 5501 this.dispatchEvent = this._dispatchEventFirefoxIE; |
| 5502 } |
| 5503 }, |
| 5504 created: function() { |
| 5505 Polymer.IronA11yAnnouncer.requestAvailability(); |
| 5506 }, |
| 5507 _canDispatchEventOnDisabled: function() { |
| 5508 var input = document.createElement('input'); |
| 5509 var canDispatch = false; |
| 5510 input.disabled = true; |
| 5511 input.addEventListener('feature-check-dispatch-event', function() { |
| 5512 canDispatch = true; |
| 5513 }); |
| 5514 try { |
| 5515 input.dispatchEvent(new Event('feature-check-dispatch-event')); |
| 5516 } catch (e) {} |
| 5517 return canDispatch; |
| 5518 }, |
| 5519 _dispatchEventFirefoxIE: function() { |
| 5520 var disabled = this.disabled; |
| 5521 this.disabled = false; |
| 5522 this._origDispatchEvent.apply(this, arguments); |
| 5523 this.disabled = disabled; |
| 5524 }, |
| 5525 get _patternRegExp() { |
| 5526 var pattern; |
| 5527 if (this.allowedPattern) { |
| 5528 pattern = new RegExp(this.allowedPattern); |
| 5529 } else { |
| 5530 switch (this.type) { |
| 5531 case 'number': |
| 5532 pattern = /[0-9.,e-]/; |
| 5533 break; |
| 5534 } |
| 5535 } |
| 5536 return pattern; |
| 5537 }, |
| 5538 ready: function() { |
| 5539 this.bindValue = this.value; |
| 5540 }, |
| 5541 _bindValueChanged: function() { |
| 5542 if (this.value !== this.bindValue) { |
| 5543 this.value = !(this.bindValue || this.bindValue === 0 || this.bindValue ==
= false) ? '' : this.bindValue; |
| 5544 } |
| 5545 this.fire('bind-value-changed', { |
| 5546 value: this.bindValue |
| 5547 }); |
| 5548 }, |
| 5549 _allowedPatternChanged: function() { |
| 5550 this.preventInvalidInput = this.allowedPattern ? true : false; |
| 5551 }, |
| 5552 _onInput: function() { |
| 5553 if (this.preventInvalidInput && !this._patternAlreadyChecked) { |
| 5554 var valid = this._checkPatternValidity(); |
| 5555 if (!valid) { |
| 5556 this._announceInvalidCharacter('Invalid string of characters not entered
.'); |
| 5557 this.value = this._previousValidInput; |
| 5558 } |
| 5559 } |
| 5560 this.bindValue = this.value; |
| 5561 this._previousValidInput = this.value; |
| 5562 this._patternAlreadyChecked = false; |
| 5563 }, |
| 5564 _isPrintable: function(event) { |
| 5565 var anyNonPrintable = event.keyCode == 8 || event.keyCode == 9 || event.keyC
ode == 13 || event.keyCode == 27; |
| 5566 var mozNonPrintable = event.keyCode == 19 || event.keyCode == 20 || event.ke
yCode == 45 || event.keyCode == 46 || event.keyCode == 144 || event.keyCode == 1
45 || event.keyCode > 32 && event.keyCode < 41 || event.keyCode > 111 && event.k
eyCode < 124; |
| 5567 return !anyNonPrintable && !(event.charCode == 0 && mozNonPrintable); |
| 5568 }, |
| 5569 _onKeypress: function(event) { |
| 5570 if (!this.preventInvalidInput && this.type !== 'number') { |
| 5571 return; |
| 5572 } |
| 5573 var regexp = this._patternRegExp; |
| 5574 if (!regexp) { |
| 5575 return; |
| 5576 } |
| 5577 if (event.metaKey || event.ctrlKey || event.altKey) return; |
| 5578 this._patternAlreadyChecked = true; |
| 5579 var thisChar = String.fromCharCode(event.charCode); |
| 5580 if (this._isPrintable(event) && !regexp.test(thisChar)) { |
| 5581 event.preventDefault(); |
| 5582 this._announceInvalidCharacter('Invalid character ' + thisChar + ' not ent
ered.'); |
| 5583 } |
| 5584 }, |
| 5585 _checkPatternValidity: function() { |
| 5586 var regexp = this._patternRegExp; |
| 5587 if (!regexp) { |
| 5588 return true; |
| 5589 } |
| 5590 for (var i = 0; i < this.value.length; i++) { |
| 5591 if (!regexp.test(this.value[i])) { |
| 5592 return false; |
| 5593 } |
| 5594 } |
| 5595 return true; |
| 5596 }, |
| 5597 validate: function() { |
| 5598 var valid = this.checkValidity(); |
| 5599 if (valid) { |
| 5600 if (this.required && this.value === '') { |
| 5601 valid = false; |
| 5602 } else if (this.hasValidator()) { |
| 5603 valid = Polymer.IronValidatableBehavior.validate.call(this, this.value); |
| 5604 } |
| 5605 } |
| 5606 this.invalid = !valid; |
| 5607 this.fire('iron-input-validate'); |
| 5608 return valid; |
| 5609 }, |
| 5610 _announceInvalidCharacter: function(message) { |
| 5611 this.fire('iron-announce', { |
| 5612 text: message |
| 5613 }); |
| 5614 } |
| 5615 }); |
| 5616 |
| 5617 Polymer({ |
| 5618 is: 'paper-input-container', |
| 5619 properties: { |
| 5620 noLabelFloat: { |
| 5621 type: Boolean, |
| 5622 value: false |
| 5623 }, |
| 5624 alwaysFloatLabel: { |
| 5625 type: Boolean, |
| 5626 value: false |
| 5627 }, |
| 5628 attrForValue: { |
| 5629 type: String, |
| 5630 value: 'bind-value' |
| 5631 }, |
| 5632 autoValidate: { |
| 5633 type: Boolean, |
| 5634 value: false |
| 5635 }, |
| 5636 invalid: { |
| 5637 observer: '_invalidChanged', |
| 5638 type: Boolean, |
| 5639 value: false |
| 5640 }, |
| 5641 focused: { |
| 5642 readOnly: true, |
| 5643 type: Boolean, |
| 5644 value: false, |
| 5645 notify: true |
| 5646 }, |
| 5647 _addons: { |
| 5648 type: Array |
| 5649 }, |
| 5650 _inputHasContent: { |
| 5651 type: Boolean, |
| 5652 value: false |
| 5653 }, |
| 5654 _inputSelector: { |
| 5655 type: String, |
| 5656 value: 'input,textarea,.paper-input-input' |
| 5657 }, |
| 5658 _boundOnFocus: { |
| 5659 type: Function, |
| 5660 value: function() { |
| 5661 return this._onFocus.bind(this); |
| 5662 } |
| 5663 }, |
| 5664 _boundOnBlur: { |
| 5665 type: Function, |
| 5666 value: function() { |
| 5667 return this._onBlur.bind(this); |
| 5668 } |
| 5669 }, |
| 5670 _boundOnInput: { |
| 5671 type: Function, |
| 5672 value: function() { |
| 5673 return this._onInput.bind(this); |
| 5674 } |
| 5675 }, |
| 5676 _boundValueChanged: { |
| 5677 type: Function, |
| 5678 value: function() { |
| 5679 return this._onValueChanged.bind(this); |
| 5680 } |
| 5681 } |
| 5682 }, |
| 5683 listeners: { |
| 5684 'addon-attached': '_onAddonAttached', |
| 5685 'iron-input-validate': '_onIronInputValidate' |
| 5686 }, |
| 5687 get _valueChangedEvent() { |
| 5688 return this.attrForValue + '-changed'; |
| 5689 }, |
| 5690 get _propertyForValue() { |
| 5691 return Polymer.CaseMap.dashToCamelCase(this.attrForValue); |
| 5692 }, |
| 5693 get _inputElement() { |
| 5694 return Polymer.dom(this).querySelector(this._inputSelector); |
| 5695 }, |
| 5696 get _inputElementValue() { |
| 5697 return this._inputElement[this._propertyForValue] || this._inputElement.valu
e; |
| 5698 }, |
| 5699 ready: function() { |
| 5700 if (!this._addons) { |
| 5701 this._addons = []; |
| 5702 } |
| 5703 this.addEventListener('focus', this._boundOnFocus, true); |
| 5704 this.addEventListener('blur', this._boundOnBlur, true); |
| 5705 }, |
| 5706 attached: function() { |
| 5707 if (this.attrForValue) { |
| 5708 this._inputElement.addEventListener(this._valueChangedEvent, this._boundVa
lueChanged); |
| 5709 } else { |
| 5710 this.addEventListener('input', this._onInput); |
| 5711 } |
| 5712 if (this._inputElementValue != '') { |
| 5713 this._handleValueAndAutoValidate(this._inputElement); |
| 5714 } else { |
| 5715 this._handleValue(this._inputElement); |
| 5716 } |
| 5717 }, |
| 5718 _onAddonAttached: function(event) { |
| 5719 if (!this._addons) { |
| 5720 this._addons = []; |
| 5721 } |
| 5722 var target = event.target; |
| 5723 if (this._addons.indexOf(target) === -1) { |
| 5724 this._addons.push(target); |
| 5725 if (this.isAttached) { |
| 5726 this._handleValue(this._inputElement); |
| 5727 } |
| 5728 } |
| 5729 }, |
| 5730 _onFocus: function() { |
| 5731 this._setFocused(true); |
| 5732 }, |
| 5733 _onBlur: function() { |
| 5734 this._setFocused(false); |
| 5735 this._handleValueAndAutoValidate(this._inputElement); |
| 5736 }, |
| 5737 _onInput: function(event) { |
| 5738 this._handleValueAndAutoValidate(event.target); |
| 5739 }, |
| 5740 _onValueChanged: function(event) { |
| 5741 this._handleValueAndAutoValidate(event.target); |
| 5742 }, |
| 5743 _handleValue: function(inputElement) { |
| 5744 var value = this._inputElementValue; |
| 5745 if (value || value === 0 || inputElement.type === 'number' && !inputElement.
checkValidity()) { |
| 5746 this._inputHasContent = true; |
| 5747 } else { |
| 5748 this._inputHasContent = false; |
| 5749 } |
| 5750 this.updateAddons({ |
| 5751 inputElement: inputElement, |
| 5752 value: value, |
| 5753 invalid: this.invalid |
| 5754 }); |
| 5755 }, |
| 5756 _handleValueAndAutoValidate: function(inputElement) { |
| 5757 if (this.autoValidate) { |
| 5758 var valid; |
| 5759 if (inputElement.validate) { |
| 5760 valid = inputElement.validate(this._inputElementValue); |
| 5761 } else { |
| 5762 valid = inputElement.checkValidity(); |
| 5763 } |
| 5764 this.invalid = !valid; |
| 5765 } |
| 5766 this._handleValue(inputElement); |
| 5767 }, |
| 5768 _onIronInputValidate: function(event) { |
| 5769 this.invalid = this._inputElement.invalid; |
| 5770 }, |
| 5771 _invalidChanged: function() { |
| 5772 if (this._addons) { |
| 5773 this.updateAddons({ |
| 5774 invalid: this.invalid |
| 5775 }); |
| 5776 } |
| 5777 }, |
| 5778 updateAddons: function(state) { |
| 5779 for (var addon, index = 0; addon = this._addons[index]; index++) { |
| 5780 addon.update(state); |
| 5781 } |
| 5782 }, |
| 5783 _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused, i
nvalid, _inputHasContent) { |
| 5784 var cls = 'input-content'; |
| 5785 if (!noLabelFloat) { |
| 5786 var label = this.querySelector('label'); |
| 5787 if (alwaysFloatLabel || _inputHasContent) { |
| 5788 cls += ' label-is-floating'; |
| 5789 this.$.labelAndInputContainer.style.position = 'static'; |
| 5790 if (invalid) { |
| 5791 cls += ' is-invalid'; |
| 5792 } else if (focused) { |
| 5793 cls += " label-is-highlighted"; |
| 5794 } |
| 5795 } else { |
| 5796 if (label) { |
| 5797 this.$.labelAndInputContainer.style.position = 'relative'; |
| 5798 } |
| 5799 } |
| 5800 } else { |
| 5801 if (_inputHasContent) { |
| 5802 cls += ' label-is-hidden'; |
| 5803 } |
| 5804 } |
| 5805 return cls; |
| 5806 }, |
| 5807 _computeUnderlineClass: function(focused, invalid) { |
| 5808 var cls = 'underline'; |
| 5809 if (invalid) { |
| 5810 cls += ' is-invalid'; |
| 5811 } else if (focused) { |
| 5812 cls += ' is-highlighted'; |
| 5813 } |
| 5814 return cls; |
| 5815 }, |
| 5816 _computeAddOnContentClass: function(focused, invalid) { |
| 5817 var cls = 'add-on-content'; |
| 5818 if (invalid) { |
| 5819 cls += ' is-invalid'; |
| 5820 } else if (focused) { |
| 5821 cls += ' is-highlighted'; |
| 5822 } |
| 5823 return cls; |
| 5824 } |
| 5825 }); |
| 5826 |
| 5827 Polymer.PaperSpinnerBehavior = { |
| 5828 listeners: { |
| 5829 animationend: '__reset', |
| 5830 webkitAnimationEnd: '__reset' |
| 5831 }, |
| 5832 properties: { |
| 5833 active: { |
| 5834 type: Boolean, |
| 5835 value: false, |
| 5836 reflectToAttribute: true, |
| 5837 observer: '__activeChanged' |
| 5838 }, |
| 5839 alt: { |
| 5840 type: String, |
| 5841 value: 'loading', |
| 5842 observer: '__altChanged' |
| 5843 }, |
| 5844 __coolingDown: { |
| 5845 type: Boolean, |
| 5846 value: false |
| 5847 } |
| 5848 }, |
| 5849 __computeContainerClasses: function(active, coolingDown) { |
| 5850 return [ active || coolingDown ? 'active' : '', coolingDown ? 'cooldown' : '
' ].join(' '); |
| 5851 }, |
| 5852 __activeChanged: function(active, old) { |
| 5853 this.__setAriaHidden(!active); |
| 5854 this.__coolingDown = !active && old; |
| 5855 }, |
| 5856 __altChanged: function(alt) { |
| 5857 if (alt === this.getPropertyInfo('alt').value) { |
| 5858 this.alt = this.getAttribute('aria-label') || alt; |
| 5859 } else { |
| 5860 this.__setAriaHidden(alt === ''); |
| 5861 this.setAttribute('aria-label', alt); |
| 5862 } |
| 5863 }, |
| 5864 __setAriaHidden: function(hidden) { |
| 5865 var attr = 'aria-hidden'; |
| 5866 if (hidden) { |
| 5867 this.setAttribute(attr, 'true'); |
| 5868 } else { |
| 5869 this.removeAttribute(attr); |
| 5870 } |
| 5871 }, |
| 5872 __reset: function() { |
| 5873 this.active = false; |
| 5874 this.__coolingDown = false; |
| 5875 } |
| 5876 }; |
| 5877 |
| 5878 Polymer({ |
| 5879 is: 'paper-spinner-lite', |
| 5880 behaviors: [ Polymer.PaperSpinnerBehavior ] |
| 5881 }); |
| 5882 |
| 5883 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 5884 // Use of this source code is governed by a BSD-style license that can be |
| 5885 // found in the LICENSE file. |
| 5886 var CrSearchFieldBehavior = { |
| 5887 properties: { |
| 5888 label: { |
| 5889 type: String, |
| 5890 value: '' |
| 5891 }, |
| 5892 clearLabel: { |
| 5893 type: String, |
| 5894 value: '' |
| 5895 }, |
| 5896 showingSearch: { |
| 5897 type: Boolean, |
| 5898 value: false, |
| 5899 notify: true, |
| 5900 observer: 'showingSearchChanged_', |
| 5901 reflectToAttribute: true |
| 5902 }, |
| 5903 lastValue_: { |
| 5904 type: String, |
| 5905 value: '' |
| 5906 } |
| 5907 }, |
| 5908 getSearchInput: function() {}, |
| 5909 getValue: function() { |
| 5910 return this.getSearchInput().value; |
| 5911 }, |
| 5912 setValue: function(value) { |
| 5913 this.getSearchInput().bindValue = value; |
| 5914 this.onValueChanged_(value); |
| 5915 }, |
| 5916 showAndFocus: function() { |
| 5917 this.showingSearch = true; |
| 5918 this.focus_(); |
| 5919 }, |
| 5920 focus_: function() { |
| 5921 this.getSearchInput().focus(); |
| 5922 }, |
| 5923 onSearchTermSearch: function() { |
| 5924 this.onValueChanged_(this.getValue()); |
| 5925 }, |
| 5926 onValueChanged_: function(newValue) { |
| 5927 if (newValue == this.lastValue_) return; |
| 5928 this.fire('search-changed', newValue); |
| 5929 this.lastValue_ = newValue; |
| 5930 }, |
| 5931 onSearchTermKeydown: function(e) { |
| 5932 if (e.key == 'Escape') this.showingSearch = false; |
| 5933 }, |
| 5934 showingSearchChanged_: function() { |
| 5935 if (this.showingSearch) { |
| 5936 this.focus_(); |
| 5937 return; |
| 5938 } |
| 5939 this.setValue(''); |
| 5940 this.getSearchInput().blur(); |
| 5941 } |
| 5942 }; |
| 5943 |
| 5944 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 5945 // Use of this source code is governed by a BSD-style license that can be |
| 5946 // found in the LICENSE file. |
| 5947 Polymer({ |
| 5948 is: 'cr-toolbar-search-field', |
| 5949 behaviors: [ CrSearchFieldBehavior ], |
| 5950 properties: { |
| 5951 narrow: { |
| 5952 type: Boolean, |
| 5953 reflectToAttribute: true |
| 5954 }, |
| 5955 label: String, |
| 5956 clearLabel: String, |
| 5957 spinnerActive: { |
| 5958 type: Boolean, |
| 5959 reflectToAttribute: true |
| 5960 }, |
| 5961 hasSearchText_: Boolean |
| 5962 }, |
| 5963 listeners: { |
| 5964 tap: 'showSearch_', |
| 5965 'searchInput.bind-value-changed': 'onBindValueChanged_' |
| 5966 }, |
| 5967 getSearchInput: function() { |
| 5968 return this.$.searchInput; |
| 5969 }, |
| 5970 isSearchFocused: function() { |
| 5971 return this.$.searchTerm.focused; |
| 5972 }, |
| 5973 computeIconTabIndex_: function(narrow) { |
| 5974 return narrow ? 0 : -1; |
| 5975 }, |
| 5976 isSpinnerShown_: function(spinnerActive, showingSearch) { |
| 5977 return spinnerActive && showingSearch; |
| 5978 }, |
| 5979 onInputBlur_: function() { |
| 5980 if (!this.hasSearchText_) this.showingSearch = false; |
| 5981 }, |
| 5982 onBindValueChanged_: function() { |
| 5983 var newValue = this.$.searchInput.bindValue; |
| 5984 this.hasSearchText_ = newValue != ''; |
| 5985 if (newValue != '') this.showingSearch = true; |
| 5986 }, |
| 5987 showSearch_: function(e) { |
| 5988 if (e.target != this.$.clearSearch) this.showingSearch = true; |
| 5989 }, |
| 5990 hideSearch_: function(e) { |
| 5991 this.showingSearch = false; |
| 5992 e.stopPropagation(); |
| 5993 } |
| 5994 }); |
| 5995 |
| 5996 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 5997 // Use of this source code is governed by a BSD-style license that can be |
| 5998 // found in the LICENSE file. |
| 5999 Polymer({ |
| 6000 is: 'cr-toolbar', |
| 6001 properties: { |
| 6002 pageName: String, |
| 6003 searchPrompt: String, |
| 6004 clearLabel: String, |
| 6005 menuLabel: String, |
| 6006 spinnerActive: Boolean, |
| 6007 showMenu: { |
| 6008 type: Boolean, |
| 6009 value: false |
| 6010 }, |
| 6011 narrow_: { |
| 6012 type: Boolean, |
| 6013 reflectToAttribute: true |
| 6014 }, |
| 6015 showingSearch_: { |
| 6016 type: Boolean, |
| 6017 reflectToAttribute: true |
| 6018 } |
| 6019 }, |
| 6020 getSearchField: function() { |
| 6021 return this.$.search; |
| 6022 }, |
| 6023 onMenuTap_: function(e) { |
| 6024 this.fire('cr-menu-tap'); |
| 6025 } |
| 6026 }); |
| 6027 |
| 6028 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 6029 // Use of this source code is governed by a BSD-style license that can be |
| 6030 // found in the LICENSE file. |
| 6031 Polymer({ |
| 6032 is: 'history-lazy-render', |
| 6033 "extends": 'template', |
| 6034 behaviors: [ Polymer.Templatizer ], |
| 6035 _renderPromise: null, |
| 6036 _instance: null, |
| 6037 get: function() { |
| 6038 if (!this._renderPromise) { |
| 6039 this._renderPromise = new Promise(function(resolve) { |
| 6040 this._debounceTemplate(function() { |
| 6041 this._render(); |
| 6042 this._renderPromise = null; |
| 6043 resolve(this.getIfExists()); |
| 6044 }.bind(this)); |
| 6045 }.bind(this)); |
| 6046 } |
| 6047 return this._renderPromise; |
| 6048 }, |
| 6049 getIfExists: function() { |
| 6050 if (this._instance) { |
| 6051 var children = this._instance._children; |
| 6052 for (var i = 0; i < children.length; i++) { |
| 6053 if (children[i].nodeType == Node.ELEMENT_NODE) return children[i]; |
| 6054 } |
| 6055 } |
| 6056 return null; |
| 6057 }, |
| 6058 _render: function() { |
| 6059 if (!this.ctor) this.templatize(this); |
| 6060 var parentNode = this.parentNode; |
| 6061 if (parentNode && !this._instance) { |
| 6062 this._instance = this.stamp({}); |
| 6063 var root = this._instance.root; |
| 6064 parentNode.insertBefore(root, this); |
| 6065 } |
| 6066 }, |
| 6067 _forwardParentProp: function(prop, value) { |
| 6068 if (this._instance) this._instance.__setProperty(prop, value, true); |
| 6069 }, |
| 6070 _forwardParentPath: function(path, value) { |
| 6071 if (this._instance) this._instance._notifyPath(path, value, true); |
| 6072 } |
| 6073 }); |
| 6074 |
| 6075 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 6076 // Use of this source code is governed by a BSD-style license that can be |
| 6077 // found in the LICENSE file. |
| 6078 Polymer({ |
| 6079 is: 'history-toolbar', |
| 6080 properties: { |
| 6081 count: { |
| 6082 type: Number, |
| 6083 value: 0, |
| 6084 observer: 'changeToolbarView_' |
| 6085 }, |
| 6086 itemsSelected_: { |
| 6087 type: Boolean, |
| 6088 value: false, |
| 6089 reflectToAttribute: true |
| 6090 }, |
| 6091 searchTerm: { |
| 6092 type: String, |
| 6093 notify: true |
| 6094 }, |
| 6095 spinnerActive: { |
| 6096 type: Boolean, |
| 6097 value: false |
| 6098 }, |
| 6099 hasDrawer: { |
| 6100 type: Boolean, |
| 6101 observer: 'hasDrawerChanged_', |
| 6102 reflectToAttribute: true |
| 6103 }, |
| 6104 showSyncNotice: Boolean, |
| 6105 isGroupedMode: { |
| 6106 type: Boolean, |
| 6107 reflectToAttribute: true |
| 6108 }, |
| 6109 groupedRange: { |
| 6110 type: Number, |
| 6111 value: 0, |
| 6112 reflectToAttribute: true, |
| 6113 notify: true |
| 6114 }, |
| 6115 queryStartTime: String, |
| 6116 queryEndTime: String |
| 6117 }, |
| 6118 changeToolbarView_: function() { |
| 6119 this.itemsSelected_ = this.count > 0; |
| 6120 }, |
| 6121 setSearchTerm: function(search) { |
| 6122 if (this.searchTerm == search) return; |
| 6123 this.searchTerm = search; |
| 6124 var searchField = this.$['main-toolbar'].getSearchField(); |
| 6125 searchField.showAndFocus(); |
| 6126 searchField.setValue(search); |
| 6127 }, |
| 6128 onSearchChanged_: function(event) { |
| 6129 this.searchTerm = event.detail; |
| 6130 }, |
| 6131 onInfoButtonTap_: function() { |
| 6132 this.$.syncNotice.get().then(function(dropdown) { |
| 6133 dropdown.positionTarget = this.$$('#info-button-icon'); |
| 6134 if (dropdown.style.display == 'none') dropdown.open(); |
| 6135 }.bind(this)); |
| 6136 }, |
| 6137 onClearSelectionTap_: function() { |
| 6138 this.fire('unselect-all'); |
| 6139 }, |
| 6140 onDeleteTap_: function() { |
| 6141 this.fire('delete-selected'); |
| 6142 }, |
| 6143 get searchBar() { |
| 6144 return this.$['main-toolbar'].getSearchField(); |
| 6145 }, |
| 6146 showSearchField: function() { |
| 6147 this.$['main-toolbar'].getSearchField().showAndFocus(); |
| 6148 }, |
| 6149 deletingAllowed_: function() { |
| 6150 return loadTimeData.getBoolean('allowDeletingHistory'); |
| 6151 }, |
| 6152 numberOfItemsSelected_: function(count) { |
| 6153 return count > 0 ? loadTimeData.getStringF('itemsSelected', count) : ''; |
| 6154 }, |
| 6155 getHistoryInterval_: function(queryStartTime, queryEndTime) { |
| 6156 return loadTimeData.getStringF('historyInterval', queryStartTime, queryEndTi
me); |
| 6157 }, |
| 6158 hasDrawerChanged_: function() { |
| 6159 this.updateStyles(); |
| 6160 } |
| 6161 }); |
| 6162 |
| 6163 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 6164 // Use of this source code is governed by a BSD-style license that can be |
| 6165 // found in the LICENSE file. |
| 6166 Polymer({ |
| 6167 is: 'cr-dialog', |
| 6168 "extends": 'dialog', |
| 6169 created: function() { |
| 6170 window.addEventListener('popstate', function() { |
| 6171 if (this.open) this.cancel(); |
| 6172 }.bind(this)); |
| 6173 }, |
| 6174 cancel: function() { |
| 6175 this.fire('cancel'); |
| 6176 HTMLDialogElement.prototype.close.call(this, ''); |
| 6177 }, |
| 6178 close: function(opt_returnValue) { |
| 6179 HTMLDialogElement.prototype.close.call(this, 'success'); |
| 6180 }, |
| 6181 getCloseButton: function() { |
| 6182 return this.$.close; |
| 6183 } |
| 6184 }); |
| 6185 |
| 6186 Polymer({ |
| 6107 is: 'fade-in-animation', | 6187 is: 'fade-in-animation', |
| 6108 behaviors: [ Polymer.NeonAnimationBehavior ], | 6188 behaviors: [ Polymer.NeonAnimationBehavior ], |
| 6109 configure: function(config) { | 6189 configure: function(config) { |
| 6110 var node = config.node; | 6190 var node = config.node; |
| 6111 this._effect = new KeyframeEffect(node, [ { | 6191 this._effect = new KeyframeEffect(node, [ { |
| 6112 opacity: '0' | 6192 opacity: '0' |
| 6113 }, { | 6193 }, { |
| 6114 opacity: '1' | 6194 opacity: '1' |
| 6115 } ], this.timingFromConfig(config)); | 6195 } ], this.timingFromConfig(config)); |
| 6116 return this._effect; | 6196 return this._effect; |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6646 }, | 6726 }, |
| 6647 _computeCheckmarkClass: function(checked) { | 6727 _computeCheckmarkClass: function(checked) { |
| 6648 return checked ? '' : 'hidden'; | 6728 return checked ? '' : 'hidden'; |
| 6649 }, | 6729 }, |
| 6650 _createRipple: function() { | 6730 _createRipple: function() { |
| 6651 this._rippleContainer = this.$.checkboxContainer; | 6731 this._rippleContainer = this.$.checkboxContainer; |
| 6652 return Polymer.PaperInkyFocusBehaviorImpl._createRipple.call(this); | 6732 return Polymer.PaperInkyFocusBehaviorImpl._createRipple.call(this); |
| 6653 } | 6733 } |
| 6654 }); | 6734 }); |
| 6655 | 6735 |
| 6656 Polymer({ | |
| 6657 is: 'paper-icon-button-light', | |
| 6658 "extends": 'button', | |
| 6659 behaviors: [ Polymer.PaperRippleBehavior ], | |
| 6660 listeners: { | |
| 6661 down: '_rippleDown', | |
| 6662 up: '_rippleUp', | |
| 6663 focus: '_rippleDown', | |
| 6664 blur: '_rippleUp' | |
| 6665 }, | |
| 6666 _rippleDown: function() { | |
| 6667 this.getRipple().downAction(); | |
| 6668 }, | |
| 6669 _rippleUp: function() { | |
| 6670 this.getRipple().upAction(); | |
| 6671 }, | |
| 6672 ensureRipple: function(var_args) { | |
| 6673 var lastRipple = this._ripple; | |
| 6674 Polymer.PaperRippleBehavior.ensureRipple.apply(this, arguments); | |
| 6675 if (this._ripple && this._ripple !== lastRipple) { | |
| 6676 this._ripple.center = true; | |
| 6677 this._ripple.classList.add('circle'); | |
| 6678 } | |
| 6679 } | |
| 6680 }); | |
| 6681 | |
| 6682 // Copyright 2016 The Chromium Authors. All rights reserved. | 6736 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 6683 // Use of this source code is governed by a BSD-style license that can be | 6737 // Use of this source code is governed by a BSD-style license that can be |
| 6684 // found in the LICENSE file. | 6738 // found in the LICENSE file. |
| 6685 cr.define('cr.icon', function() { | 6739 cr.define('cr.icon', function() { |
| 6686 function getSupportedScaleFactors() { | 6740 function getSupportedScaleFactors() { |
| 6687 var supportedScaleFactors = []; | 6741 var supportedScaleFactors = []; |
| 6742 if (!cr.isIOS) { |
| 6743 supportedScaleFactors.push(1); |
| 6744 } |
| 6688 if (cr.isMac || cr.isChromeOS || cr.isWindows || cr.isLinux) { | 6745 if (cr.isMac || cr.isChromeOS || cr.isWindows || cr.isLinux) { |
| 6689 supportedScaleFactors.push(1); | |
| 6690 supportedScaleFactors.push(2); | 6746 supportedScaleFactors.push(2); |
| 6691 } else { | 6747 } else { |
| 6692 supportedScaleFactors.push(window.devicePixelRatio); | 6748 supportedScaleFactors.push(window.devicePixelRatio); |
| 6693 } | 6749 } |
| 6694 return supportedScaleFactors; | 6750 return supportedScaleFactors; |
| 6695 } | 6751 } |
| 6696 function getProfileAvatarIcon(path) { | 6752 function getImageSet(path) { |
| 6697 var chromeThemePath = 'chrome://theme'; | |
| 6698 var isDefaultAvatar = path.slice(0, chromeThemePath.length) == chromeThemePa
th; | |
| 6699 return isDefaultAvatar ? imageset(path + '@scalefactorx') : url(path); | |
| 6700 } | |
| 6701 function imageset(path) { | |
| 6702 var supportedScaleFactors = getSupportedScaleFactors(); | 6753 var supportedScaleFactors = getSupportedScaleFactors(); |
| 6703 var replaceStartIndex = path.indexOf('scalefactor'); | 6754 var replaceStartIndex = path.indexOf('scalefactor'); |
| 6704 if (replaceStartIndex < 0) return url(path); | 6755 if (replaceStartIndex < 0) return url(path); |
| 6705 var s = ''; | 6756 var s = ''; |
| 6706 for (var i = 0; i < supportedScaleFactors.length; ++i) { | 6757 for (var i = 0; i < supportedScaleFactors.length; ++i) { |
| 6707 var scaleFactor = supportedScaleFactors[i]; | 6758 var scaleFactor = supportedScaleFactors[i]; |
| 6708 var pathWithScaleFactor = path.substr(0, replaceStartIndex) + scaleFactor
+ path.substr(replaceStartIndex + 'scalefactor'.length); | 6759 var pathWithScaleFactor = path.substr(0, replaceStartIndex) + scaleFactor
+ path.substr(replaceStartIndex + 'scalefactor'.length); |
| 6709 s += url(pathWithScaleFactor) + ' ' + scaleFactor + 'x'; | 6760 s += url(pathWithScaleFactor) + ' ' + scaleFactor + 'x'; |
| 6710 if (i != supportedScaleFactors.length - 1) s += ', '; | 6761 if (i != supportedScaleFactors.length - 1) s += ', '; |
| 6711 } | 6762 } |
| 6712 return '-webkit-image-set(' + s + ')'; | 6763 return '-webkit-image-set(' + s + ')'; |
| 6713 } | 6764 } |
| 6765 function getImage(path) { |
| 6766 var chromeThemePath = 'chrome://theme'; |
| 6767 var isChromeThemeUrl = path.slice(0, chromeThemePath.length) == chromeThemeP
ath; |
| 6768 return isChromeThemeUrl ? getImageSet(path + '@scalefactorx') : url(path); |
| 6769 } |
| 6714 var FAVICON_URL_REGEX = /\.ico$/i; | 6770 var FAVICON_URL_REGEX = /\.ico$/i; |
| 6715 function getFaviconImageSet(url, opt_size, opt_type) { | 6771 function getFavicon(url, opt_size, opt_type) { |
| 6716 var size = opt_size || 16; | 6772 var size = opt_size || 16; |
| 6717 var type = opt_type || 'favicon'; | 6773 var type = opt_type || 'favicon'; |
| 6718 return imageset('chrome://' + type + '/size/' + size + '@scalefactorx/' + (F
AVICON_URL_REGEX.test(url) ? 'iconurl/' : '') + url); | 6774 return getImageSet('chrome://' + type + '/size/' + size + '@scalefactorx/' +
(FAVICON_URL_REGEX.test(url) ? 'iconurl/' : '') + url); |
| 6719 } | 6775 } |
| 6720 return { | 6776 return { |
| 6721 getSupportedScaleFactors: getSupportedScaleFactors, | 6777 getImage: getImage, |
| 6722 getProfileAvatarIcon: getProfileAvatarIcon, | 6778 getFavicon: getFavicon |
| 6723 getFaviconImageSet: getFaviconImageSet | |
| 6724 }; | 6779 }; |
| 6725 }); | 6780 }); |
| 6726 | 6781 |
| 6727 // Copyright 2016 The Chromium Authors. All rights reserved. | 6782 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 6728 // Use of this source code is governed by a BSD-style license that can be | 6783 // Use of this source code is governed by a BSD-style license that can be |
| 6729 // found in the LICENSE file. | 6784 // found in the LICENSE file. |
| 6730 Polymer({ | 6785 Polymer({ |
| 6731 is: 'history-searched-label', | 6786 is: 'history-searched-label', |
| 6732 properties: { | 6787 properties: { |
| 6733 title: String, | 6788 title: String, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6837 if (this.index == undefined) return; | 6892 if (this.index == undefined) return; |
| 6838 browserService.recordHistogram('HistoryPage.ClickPosition', this.index, UM
A_MAX_BUCKET_VALUE); | 6893 browserService.recordHistogram('HistoryPage.ClickPosition', this.index, UM
A_MAX_BUCKET_VALUE); |
| 6839 if (this.index <= UMA_MAX_SUBSET_BUCKET_VALUE) { | 6894 if (this.index <= UMA_MAX_SUBSET_BUCKET_VALUE) { |
| 6840 browserService.recordHistogram('HistoryPage.ClickPositionSubset', this.i
ndex, UMA_MAX_SUBSET_BUCKET_VALUE); | 6895 browserService.recordHistogram('HistoryPage.ClickPositionSubset', this.i
ndex, UMA_MAX_SUBSET_BUCKET_VALUE); |
| 6841 } | 6896 } |
| 6842 }, | 6897 }, |
| 6843 onLinkRightClick_: function() { | 6898 onLinkRightClick_: function() { |
| 6844 md_history.BrowserService.getInstance().recordAction('EntryLinkRightClick'
); | 6899 md_history.BrowserService.getInstance().recordAction('EntryLinkRightClick'
); |
| 6845 }, | 6900 }, |
| 6846 showIcon_: function() { | 6901 showIcon_: function() { |
| 6847 this.$.icon.style.backgroundImage = cr.icon.getFaviconImageSet(this.item.u
rl); | 6902 this.$.icon.style.backgroundImage = cr.icon.getFavicon(this.item.url); |
| 6848 }, | 6903 }, |
| 6849 selectionNotAllowed_: function() { | 6904 selectionNotAllowed_: function() { |
| 6850 return !loadTimeData.getBoolean('allowDeletingHistory'); | 6905 return !loadTimeData.getBoolean('allowDeletingHistory'); |
| 6851 }, | 6906 }, |
| 6852 cardTitle_: function(numberOfItems, historyDate, search) { | 6907 cardTitle_: function(numberOfItems, historyDate, search) { |
| 6853 if (!search) return this.item.dateRelativeDay; | 6908 if (!search) return this.item.dateRelativeDay; |
| 6854 var resultId = numberOfItems == 1 ? 'searchResult' : 'searchResults'; | 6909 var resultId = numberOfItems == 1 ? 'searchResult' : 'searchResults'; |
| 6855 return loadTimeData.getStringF('foundSearchResults', numberOfItems, loadTi
meData.getString(resultId), search); | 6910 return loadTimeData.getStringF('foundSearchResults', numberOfItems, loadTi
meData.getString(resultId), search); |
| 6856 }, | 6911 }, |
| 6857 cropItemTitle_: function(title) { | 6912 cropItemTitle_: function(title) { |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7086 }, 0); | 7141 }, 0); |
| 7087 }, | 7142 }, |
| 7088 needsTimeGap_: function(groupIndex, domainIndex, itemIndex) { | 7143 needsTimeGap_: function(groupIndex, domainIndex, itemIndex) { |
| 7089 var visits = this.groupedHistoryData_[groupIndex].domains[domainIndex].visit
s; | 7144 var visits = this.groupedHistoryData_[groupIndex].domains[domainIndex].visit
s; |
| 7090 return md_history.HistoryItem.needsTimeGap(visits, itemIndex, this.searchedT
erm); | 7145 return md_history.HistoryItem.needsTimeGap(visits, itemIndex, this.searchedT
erm); |
| 7091 }, | 7146 }, |
| 7092 pathForItem_: function(groupIndex, domainIndex, itemIndex) { | 7147 pathForItem_: function(groupIndex, domainIndex, itemIndex) { |
| 7093 return [ 'groupedHistoryData_', groupIndex, 'domains', domainIndex, 'visits'
, itemIndex ].join('.'); | 7148 return [ 'groupedHistoryData_', groupIndex, 'domains', domainIndex, 'visits'
, itemIndex ].join('.'); |
| 7094 }, | 7149 }, |
| 7095 getWebsiteIconStyle_: function(domain) { | 7150 getWebsiteIconStyle_: function(domain) { |
| 7096 return 'background-image: ' + cr.icon.getFaviconImageSet(domain.visits[0].ur
l); | 7151 return 'background-image: ' + cr.icon.getFavicon(domain.visits[0].url); |
| 7097 }, | 7152 }, |
| 7098 getDropdownIcon_: function(expanded) { | 7153 getDropdownIcon_: function(expanded) { |
| 7099 return expanded ? 'cr:expand-less' : 'cr:expand-more'; | 7154 return expanded ? 'cr:expand-less' : 'cr:expand-more'; |
| 7100 } | 7155 } |
| 7101 }); | 7156 }); |
| 7102 | 7157 |
| 7103 (function() { | 7158 (function() { |
| 7104 var IOS = navigator.userAgent.match(/iP(?:hone|ad;(?: U;)? CPU) OS (\d+)/); | 7159 var IOS = navigator.userAgent.match(/iP(?:hone|ad;(?: U;)? CPU) OS (\d+)/); |
| 7105 var IOS_TOUCH_SCROLLING = IOS && IOS[1] >= 8; | 7160 var IOS_TOUCH_SCROLLING = IOS && IOS[1] >= 8; |
| 7106 var DEFAULT_PHYSICAL_COUNT = 3; | 7161 var DEFAULT_PHYSICAL_COUNT = 3; |
| (...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8116 }, | 8171 }, |
| 8117 pathForItem_: function(index) { | 8172 pathForItem_: function(index) { |
| 8118 return 'historyData_.' + index; | 8173 return 'historyData_.' + index; |
| 8119 } | 8174 } |
| 8120 }); | 8175 }); |
| 8121 | 8176 |
| 8122 // Copyright 2016 The Chromium Authors. All rights reserved. | 8177 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 8123 // Use of this source code is governed by a BSD-style license that can be | 8178 // Use of this source code is governed by a BSD-style license that can be |
| 8124 // found in the LICENSE file. | 8179 // found in the LICENSE file. |
| 8125 Polymer({ | 8180 Polymer({ |
| 8126 is: 'history-lazy-render', | |
| 8127 "extends": 'template', | |
| 8128 behaviors: [ Polymer.Templatizer ], | |
| 8129 _renderPromise: null, | |
| 8130 _instance: null, | |
| 8131 get: function() { | |
| 8132 if (!this._renderPromise) { | |
| 8133 this._renderPromise = new Promise(function(resolve) { | |
| 8134 this._debounceTemplate(function() { | |
| 8135 this._render(); | |
| 8136 this._renderPromise = null; | |
| 8137 resolve(this.getIfExists()); | |
| 8138 }.bind(this)); | |
| 8139 }.bind(this)); | |
| 8140 } | |
| 8141 return this._renderPromise; | |
| 8142 }, | |
| 8143 getIfExists: function() { | |
| 8144 if (this._instance) { | |
| 8145 var children = this._instance._children; | |
| 8146 for (var i = 0; i < children.length; i++) { | |
| 8147 if (children[i].nodeType == Node.ELEMENT_NODE) return children[i]; | |
| 8148 } | |
| 8149 } | |
| 8150 return null; | |
| 8151 }, | |
| 8152 _render: function() { | |
| 8153 if (!this.ctor) this.templatize(this); | |
| 8154 var parentNode = this.parentNode; | |
| 8155 if (parentNode && !this._instance) { | |
| 8156 this._instance = this.stamp({}); | |
| 8157 var root = this._instance.root; | |
| 8158 parentNode.insertBefore(root, this); | |
| 8159 } | |
| 8160 }, | |
| 8161 _forwardParentProp: function(prop, value) { | |
| 8162 if (this._instance) this._instance.__setProperty(prop, value, true); | |
| 8163 }, | |
| 8164 _forwardParentPath: function(path, value) { | |
| 8165 if (this._instance) this._instance._notifyPath(path, value, true); | |
| 8166 } | |
| 8167 }); | |
| 8168 | |
| 8169 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 8170 // Use of this source code is governed by a BSD-style license that can be | |
| 8171 // found in the LICENSE file. | |
| 8172 Polymer({ | |
| 8173 is: 'history-list-container', | 8181 is: 'history-list-container', |
| 8174 properties: { | 8182 properties: { |
| 8175 selectedPage_: String, | 8183 selectedPage_: String, |
| 8176 grouped: Boolean, | 8184 grouped: Boolean, |
| 8177 groupedRange: { | 8185 groupedRange: { |
| 8178 type: Number, | 8186 type: Number, |
| 8179 observer: 'groupedRangeChanged_' | 8187 observer: 'groupedRangeChanged_' |
| 8180 }, | 8188 }, |
| 8181 queryState: Object, | 8189 queryState: Object, |
| 8182 queryResult: Object | 8190 queryResult: Object |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8340 toggleTabCard: function() { | 8348 toggleTabCard: function() { |
| 8341 var histogramValue = this.$.collapse.opened ? SyncedTabsHistogram.COLLAPSE_S
ESSION : SyncedTabsHistogram.EXPAND_SESSION; | 8349 var histogramValue = this.$.collapse.opened ? SyncedTabsHistogram.COLLAPSE_S
ESSION : SyncedTabsHistogram.EXPAND_SESSION; |
| 8342 md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRA
M_NAME, histogramValue, SyncedTabsHistogram.LIMIT); | 8350 md_history.BrowserService.getInstance().recordHistogram(SYNCED_TABS_HISTOGRA
M_NAME, histogramValue, SyncedTabsHistogram.LIMIT); |
| 8343 this.$.collapse.toggle(); | 8351 this.$.collapse.toggle(); |
| 8344 this.$['dropdown-indicator'].icon = this.$.collapse.opened ? 'cr:expand-less
' : 'cr:expand-more'; | 8352 this.$['dropdown-indicator'].icon = this.$.collapse.opened ? 'cr:expand-less
' : 'cr:expand-more'; |
| 8345 }, | 8353 }, |
| 8346 updateIcons_: function() { | 8354 updateIcons_: function() { |
| 8347 this.async(function() { | 8355 this.async(function() { |
| 8348 var icons = Polymer.dom(this.root).querySelectorAll('.website-icon'); | 8356 var icons = Polymer.dom(this.root).querySelectorAll('.website-icon'); |
| 8349 for (var i = 0; i < this.tabs.length; i++) { | 8357 for (var i = 0; i < this.tabs.length; i++) { |
| 8350 icons[i].style.backgroundImage = cr.icon.getFaviconImageSet(this.tabs[i]
.url); | 8358 icons[i].style.backgroundImage = cr.icon.getFavicon(this.tabs[i].url); |
| 8351 } | 8359 } |
| 8352 }); | 8360 }); |
| 8353 }, | 8361 }, |
| 8354 isWindowSeparatorIndex_: function(index, separatorIndexes) { | 8362 isWindowSeparatorIndex_: function(index, separatorIndexes) { |
| 8355 return this.separatorIndexes.indexOf(index) != -1; | 8363 return this.separatorIndexes.indexOf(index) != -1; |
| 8356 }, | 8364 }, |
| 8357 getCollapseIcon_: function(opened) { | 8365 getCollapseIcon_: function(opened) { |
| 8358 return opened ? 'cr:expand-less' : 'cr:expand-more'; | 8366 return opened ? 'cr:expand-less' : 'cr:expand-more'; |
| 8359 }, | 8367 }, |
| 8360 getCollapseTitle_: function(opened) { | 8368 getCollapseTitle_: function(opened) { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8585 }); | 8593 }); |
| 8586 | 8594 |
| 8587 // Copyright 2016 The Chromium Authors. All rights reserved. | 8595 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 8588 // Use of this source code is governed by a BSD-style license that can be | 8596 // Use of this source code is governed by a BSD-style license that can be |
| 8589 // found in the LICENSE file. | 8597 // found in the LICENSE file. |
| 8590 Polymer({ | 8598 Polymer({ |
| 8591 is: 'history-app', | 8599 is: 'history-app', |
| 8592 behaviors: [ Polymer.IronScrollTargetBehavior ], | 8600 behaviors: [ Polymer.IronScrollTargetBehavior ], |
| 8593 properties: { | 8601 properties: { |
| 8594 showSidebarFooter: Boolean, | 8602 showSidebarFooter: Boolean, |
| 8603 hasSyncedResults: Boolean, |
| 8595 selectedPage_: { | 8604 selectedPage_: { |
| 8596 type: String, | 8605 type: String, |
| 8597 observer: 'unselectAll' | 8606 observer: 'unselectAll' |
| 8598 }, | 8607 }, |
| 8599 grouped_: { | 8608 grouped_: { |
| 8600 type: Boolean, | 8609 type: Boolean, |
| 8601 reflectToAttribute: true | 8610 reflectToAttribute: true |
| 8602 }, | 8611 }, |
| 8603 queryState_: { | 8612 queryState_: { |
| 8604 type: Object, | 8613 type: Object, |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8743 }, | 8752 }, |
| 8744 updateSignInState: function(isUserSignedIn) { | 8753 updateSignInState: function(isUserSignedIn) { |
| 8745 this.isUserSignedIn_ = isUserSignedIn; | 8754 this.isUserSignedIn_ = isUserSignedIn; |
| 8746 }, | 8755 }, |
| 8747 syncedTabsSelected_: function(selectedPage) { | 8756 syncedTabsSelected_: function(selectedPage) { |
| 8748 return selectedPage == 'syncedTabs'; | 8757 return selectedPage == 'syncedTabs'; |
| 8749 }, | 8758 }, |
| 8750 shouldShowSpinner_: function(querying, incremental, searchTerm) { | 8759 shouldShowSpinner_: function(querying, incremental, searchTerm) { |
| 8751 return querying && !incremental && searchTerm != ''; | 8760 return querying && !incremental && searchTerm != ''; |
| 8752 }, | 8761 }, |
| 8762 showSyncNotice_: function(hasSyncedResults, selectedPage) { |
| 8763 return hasSyncedResults && selectedPage != 'syncedTabs'; |
| 8764 }, |
| 8753 routeDataChanged_: function(page) { | 8765 routeDataChanged_: function(page) { |
| 8754 this.selectedPage_ = page; | 8766 this.selectedPage_ = page; |
| 8755 }, | 8767 }, |
| 8756 selectedPageChanged_: function(selectedPage) { | 8768 selectedPageChanged_: function(selectedPage) { |
| 8757 this.set('routeData_.page', selectedPage); | 8769 this.set('routeData_.page', selectedPage); |
| 8758 this.historyViewChanged_(); | 8770 this.historyViewChanged_(); |
| 8759 }, | 8771 }, |
| 8760 historyViewChanged_: function() { | 8772 historyViewChanged_: function() { |
| 8761 requestAnimationFrame(function() { | 8773 requestAnimationFrame(function() { |
| 8762 this.scrollTarget = this.$.content.selectedItem.getContentScrollTarget(); | 8774 this.scrollTarget = this.$.content.selectedItem.getContentScrollTarget(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 8790 | 8802 |
| 8791 case HistoryRange.MONTH: | 8803 case HistoryRange.MONTH: |
| 8792 histogramValue = HistoryPageViewHistogram.GROUPED_MONTH; | 8804 histogramValue = HistoryPageViewHistogram.GROUPED_MONTH; |
| 8793 break; | 8805 break; |
| 8794 } | 8806 } |
| 8795 break; | 8807 break; |
| 8796 } | 8808 } |
| 8797 md_history.BrowserService.getInstance().recordHistogram('History.HistoryPage
View', histogramValue, HistoryPageViewHistogram.END); | 8809 md_history.BrowserService.getInstance().recordHistogram('History.HistoryPage
View', histogramValue, HistoryPageViewHistogram.END); |
| 8798 } | 8810 } |
| 8799 }); | 8811 }); |
| OLD | NEW |