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

Side by Side Diff: chrome/browser/resources/md_history/app.crisper.js

Issue 2371383003: MD Downloads/History: make javascript uglier and more compact (Closed)
Patch Set: merge Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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(){this.resolve_;this.reject_;this.promise_=new Promise( function(resolve,reject){this.resolve_=resolve;this.reject_=reject}.bind(this))} PromiseResolver.prototype={get promise(){return this.promise_},set promise(p){as sertNotReached()},get resolve(){return this.resolve_},set resolve(r){assertNotRe ached()},get reject(){return this.reject_},set reject(s){assertNotReached()}};
5 this.resolve_;
6 this.reject_;
7 this.promise_ = new Promise(function(resolve, reject) {
8 this.resolve_ = resolve;
9 this.reject_ = reject;
10 }.bind(this));
11 }
12
13 PromiseResolver.prototype = {
14 get promise() {
15 return this.promise_;
16 },
17 set promise(p) {
18 assertNotReached();
19 },
20 get resolve() {
21 return this.resolve_;
22 },
23 set resolve(r) {
24 assertNotReached();
25 },
26 get reject() {
27 return this.reject_;
28 },
29 set reject(s) {
30 assertNotReached();
31 }
32 };
33
34 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 5 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
35 // Use of this source code is governed by a BSD-style license that can be 6 // Use of this source code is governed by a BSD-style license that can be
36 // found in the LICENSE file. 7 // found in the LICENSE file.
37 var global = this; 8 var global=this;var WebUIListener;var cr=cr||function(){"use strict";function ex portPath(name,opt_object,opt_objectToExportTo){var parts=name.split(".");var cur =opt_objectToExportTo||global;for(var part;parts.length&&(part=parts.shift());){ if(!parts.length&&opt_object!==undefined){cur[part]=opt_object}else if(part in c ur){cur=cur[part]}else{cur=cur[part]={}}}return cur}function dispatchPropertyCha nge(target,propertyName,newValue,oldValue){var e=new Event(propertyName+"Change" );e.propertyName=propertyName;e.newValue=newValue;e.oldValue=oldValue;target.dis patchEvent(e)}function getAttributeName(jsName){return jsName.replace(/([A-Z])/g ,"-$1").toLowerCase()}var PropertyKind={JS:"js",ATTR:"attr",BOOL_ATTR:"boolAttr" };function getGetter(name,kind){switch(kind){case PropertyKind.JS:var privateNam e=name+"_";return function(){return this[privateName]};case PropertyKind.ATTR:va r attributeName=getAttributeName(name);return function(){return this.getAttribut e(attributeName)};case PropertyKind.BOOL_ATTR:var attributeName=getAttributeName (name);return function(){return this.hasAttribute(attributeName)}}throw"not reac hed"}function getSetter(name,kind,opt_setHook){switch(kind){case PropertyKind.JS :var privateName=name+"_";return function(value){var oldValue=this[name];if(valu e!==oldValue){this[privateName]=value;if(opt_setHook)opt_setHook.call(this,value ,oldValue);dispatchPropertyChange(this,name,value,oldValue)}};case PropertyKind. ATTR:var attributeName=getAttributeName(name);return function(value){var oldValu e=this[name];if(value!==oldValue){if(value==undefined)this.removeAttribute(attri buteName);else this.setAttribute(attributeName,value);if(opt_setHook)opt_setHook .call(this,value,oldValue);dispatchPropertyChange(this,name,value,oldValue)}};ca se PropertyKind.BOOL_ATTR:var attributeName=getAttributeName(name);return functi on(value){var oldValue=this[name];if(value!==oldValue){if(value)this.setAttribut e(attributeName,name);else this.removeAttribute(attributeName);if(opt_setHook)op t_setHook.call(this,value,oldValue);dispatchPropertyChange(this,name,value,oldVa lue)}}}throw"not reached"}function defineProperty(obj,name,opt_kind,opt_setHook) {if(typeof obj=="function")obj=obj.prototype;var kind=opt_kind||PropertyKind.JS; if(!obj.__lookupGetter__(name))obj.__defineGetter__(name,getGetter(name,kind));i f(!obj.__lookupSetter__(name))obj.__defineSetter__(name,getSetter(name,kind,opt_ setHook))}var uidCounter=1;function createUid(){return uidCounter++}function get Uid(item){if(item.hasOwnProperty("uid"))return item.uid;return item.uid=createUi d()}function dispatchSimpleEvent(target,type,opt_bubbles,opt_cancelable){var e=n ew Event(type,{bubbles:opt_bubbles,cancelable:opt_cancelable===undefined||opt_ca ncelable});return target.dispatchEvent(e)}function define(name,fun){var obj=expo rtPath(name);var exports=fun();for(var propertyName in exports){var propertyDesc riptor=Object.getOwnPropertyDescriptor(exports,propertyName);if(propertyDescript or)Object.defineProperty(obj,propertyName,propertyDescriptor)}}function addSingl etonGetter(ctor){ctor.getInstance=function(){return ctor.instance_||(ctor.instan ce_=new ctor)}}function makePublic(ctor,methods,opt_target){methods.forEach(func tion(method){ctor[method]=function(){var target=opt_target?document.getElementBy Id(opt_target):ctor.getInstance();return target[method+"_"].apply(target,argumen ts)}})}var chromeSendResolverMap={};function webUIResponse(id,isSuccess,response ){var resolver=chromeSendResolverMap[id];delete chromeSendResolverMap[id];if(isS uccess)resolver.resolve(response);else resolver.reject(response)}function sendWi thPromise(methodName,var_args){var args=Array.prototype.slice.call(arguments,1); var promiseResolver=new PromiseResolver;var id=methodName+"_"+createUid();chrome SendResolverMap[id]=promiseResolver;chrome.send(methodName,[id].concat(args));re turn promiseResolver.promise}var webUIListenerMap={};function webUIListenerCallb ack(event,var_args){var eventListenersMap=webUIListenerMap[event];if(!eventListe nersMap){return}var args=Array.prototype.slice.call(arguments,1);for(var listene rId in eventListenersMap){eventListenersMap[listenerId].apply(null,args)}}functi on addWebUIListener(eventName,callback){webUIListenerMap[eventName]=webUIListene rMap[eventName]||{};var uid=createUid();webUIListenerMap[eventName][uid]=callbac k;return{eventName:eventName,uid:uid}}function removeWebUIListener(listener){var listenerExists=webUIListenerMap[listener.eventName]&&webUIListenerMap[listener. eventName][listener.uid];if(listenerExists){delete webUIListenerMap[listener.eve ntName][listener.uid];return true}return false}return{addSingletonGetter:addSing letonGetter,createUid:createUid,define:define,defineProperty:defineProperty,disp atchPropertyChange:dispatchPropertyChange,dispatchSimpleEvent:dispatchSimpleEven t,exportPath:exportPath,getUid:getUid,makePublic:makePublic,PropertyKind:Propert yKind,addWebUIListener:addWebUIListener,removeWebUIListener:removeWebUIListener, sendWithPromise:sendWithPromise,webUIListenerCallback:webUIListenerCallback,webU IResponse:webUIResponse,get doc(){return document},get isMac(){return/Mac/.test( navigator.platform)},get isWindows(){return/Win/.test(navigator.platform)},get i sChromeOS(){return/CrOS/.test(navigator.userAgent)},get isLinux(){return/Linux/. test(navigator.userAgent)},get isAndroid(){return/Android/.test(navigator.userAg ent)},get isIOS(){return/iPad|iPhone|iPod/.test(navigator.platform)}}}();
38
39 var WebUIListener;
40
41 var cr = cr || function() {
42 'use strict';
43 function exportPath(name, opt_object, opt_objectToExportTo) {
44 var parts = name.split('.');
45 var cur = opt_objectToExportTo || global;
46 for (var part; parts.length && (part = parts.shift()); ) {
47 if (!parts.length && opt_object !== undefined) {
48 cur[part] = opt_object;
49 } else if (part in cur) {
50 cur = cur[part];
51 } else {
52 cur = cur[part] = {};
53 }
54 }
55 return cur;
56 }
57 function dispatchPropertyChange(target, propertyName, newValue, oldValue) {
58 var e = new Event(propertyName + 'Change');
59 e.propertyName = propertyName;
60 e.newValue = newValue;
61 e.oldValue = oldValue;
62 target.dispatchEvent(e);
63 }
64 function getAttributeName(jsName) {
65 return jsName.replace(/([A-Z])/g, '-$1').toLowerCase();
66 }
67 var PropertyKind = {
68 JS: 'js',
69 ATTR: 'attr',
70 BOOL_ATTR: 'boolAttr'
71 };
72 function getGetter(name, kind) {
73 switch (kind) {
74 case PropertyKind.JS:
75 var privateName = name + '_';
76 return function() {
77 return this[privateName];
78 };
79
80 case PropertyKind.ATTR:
81 var attributeName = getAttributeName(name);
82 return function() {
83 return this.getAttribute(attributeName);
84 };
85
86 case PropertyKind.BOOL_ATTR:
87 var attributeName = getAttributeName(name);
88 return function() {
89 return this.hasAttribute(attributeName);
90 };
91 }
92 throw 'not reached';
93 }
94 function getSetter(name, kind, opt_setHook) {
95 switch (kind) {
96 case PropertyKind.JS:
97 var privateName = name + '_';
98 return function(value) {
99 var oldValue = this[name];
100 if (value !== oldValue) {
101 this[privateName] = value;
102 if (opt_setHook) opt_setHook.call(this, value, oldValue);
103 dispatchPropertyChange(this, name, value, oldValue);
104 }
105 };
106
107 case PropertyKind.ATTR:
108 var attributeName = getAttributeName(name);
109 return function(value) {
110 var oldValue = this[name];
111 if (value !== oldValue) {
112 if (value == undefined) this.removeAttribute(attributeName); else this .setAttribute(attributeName, value);
113 if (opt_setHook) opt_setHook.call(this, value, oldValue);
114 dispatchPropertyChange(this, name, value, oldValue);
115 }
116 };
117
118 case PropertyKind.BOOL_ATTR:
119 var attributeName = getAttributeName(name);
120 return function(value) {
121 var oldValue = this[name];
122 if (value !== oldValue) {
123 if (value) this.setAttribute(attributeName, name); else this.removeAtt ribute(attributeName);
124 if (opt_setHook) opt_setHook.call(this, value, oldValue);
125 dispatchPropertyChange(this, name, value, oldValue);
126 }
127 };
128 }
129 throw 'not reached';
130 }
131 function defineProperty(obj, name, opt_kind, opt_setHook) {
132 if (typeof obj == 'function') obj = obj.prototype;
133 var kind = opt_kind || PropertyKind.JS;
134 if (!obj.__lookupGetter__(name)) obj.__defineGetter__(name, getGetter(name, kind));
135 if (!obj.__lookupSetter__(name)) obj.__defineSetter__(name, getSetter(name, kind, opt_setHook));
136 }
137 var uidCounter = 1;
138 function createUid() {
139 return uidCounter++;
140 }
141 function getUid(item) {
142 if (item.hasOwnProperty('uid')) return item.uid;
143 return item.uid = createUid();
144 }
145 function dispatchSimpleEvent(target, type, opt_bubbles, opt_cancelable) {
146 var e = new Event(type, {
147 bubbles: opt_bubbles,
148 cancelable: opt_cancelable === undefined || opt_cancelable
149 });
150 return target.dispatchEvent(e);
151 }
152 function define(name, fun) {
153 var obj = exportPath(name);
154 var exports = fun();
155 for (var propertyName in exports) {
156 var propertyDescriptor = Object.getOwnPropertyDescriptor(exports, property Name);
157 if (propertyDescriptor) Object.defineProperty(obj, propertyName, propertyD escriptor);
158 }
159 }
160 function addSingletonGetter(ctor) {
161 ctor.getInstance = function() {
162 return ctor.instance_ || (ctor.instance_ = new ctor());
163 };
164 }
165 function makePublic(ctor, methods, opt_target) {
166 methods.forEach(function(method) {
167 ctor[method] = function() {
168 var target = opt_target ? document.getElementById(opt_target) : ctor.get Instance();
169 return target[method + '_'].apply(target, arguments);
170 };
171 });
172 }
173 var chromeSendResolverMap = {};
174 function webUIResponse(id, isSuccess, response) {
175 var resolver = chromeSendResolverMap[id];
176 delete chromeSendResolverMap[id];
177 if (isSuccess) resolver.resolve(response); else resolver.reject(response);
178 }
179 function sendWithPromise(methodName, var_args) {
180 var args = Array.prototype.slice.call(arguments, 1);
181 var promiseResolver = new PromiseResolver();
182 var id = methodName + '_' + createUid();
183 chromeSendResolverMap[id] = promiseResolver;
184 chrome.send(methodName, [ id ].concat(args));
185 return promiseResolver.promise;
186 }
187 var webUIListenerMap = {};
188 function webUIListenerCallback(event, var_args) {
189 var eventListenersMap = webUIListenerMap[event];
190 if (!eventListenersMap) {
191 return;
192 }
193 var args = Array.prototype.slice.call(arguments, 1);
194 for (var listenerId in eventListenersMap) {
195 eventListenersMap[listenerId].apply(null, args);
196 }
197 }
198 function addWebUIListener(eventName, callback) {
199 webUIListenerMap[eventName] = webUIListenerMap[eventName] || {};
200 var uid = createUid();
201 webUIListenerMap[eventName][uid] = callback;
202 return {
203 eventName: eventName,
204 uid: uid
205 };
206 }
207 function removeWebUIListener(listener) {
208 var listenerExists = webUIListenerMap[listener.eventName] && webUIListenerMa p[listener.eventName][listener.uid];
209 if (listenerExists) {
210 delete webUIListenerMap[listener.eventName][listener.uid];
211 return true;
212 }
213 return false;
214 }
215 return {
216 addSingletonGetter: addSingletonGetter,
217 createUid: createUid,
218 define: define,
219 defineProperty: defineProperty,
220 dispatchPropertyChange: dispatchPropertyChange,
221 dispatchSimpleEvent: dispatchSimpleEvent,
222 exportPath: exportPath,
223 getUid: getUid,
224 makePublic: makePublic,
225 PropertyKind: PropertyKind,
226 addWebUIListener: addWebUIListener,
227 removeWebUIListener: removeWebUIListener,
228 sendWithPromise: sendWithPromise,
229 webUIListenerCallback: webUIListenerCallback,
230 webUIResponse: webUIResponse,
231 get doc() {
232 return document;
233 },
234 get isMac() {
235 return /Mac/.test(navigator.platform);
236 },
237 get isWindows() {
238 return /Win/.test(navigator.platform);
239 },
240 get isChromeOS() {
241 return /CrOS/.test(navigator.userAgent);
242 },
243 get isLinux() {
244 return /Linux/.test(navigator.userAgent);
245 },
246 get isAndroid() {
247 return /Android/.test(navigator.userAgent);
248 },
249 get isIOS() {
250 return /iPad|iPhone|iPod/.test(navigator.platform);
251 }
252 };
253 }();
254
255 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 9 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
256 // Use of this source code is governed by a BSD-style license that can be 10 // Use of this source code is governed by a BSD-style license that can be
257 // found in the LICENSE file. 11 // found in the LICENSE file.
258 cr.define('cr.ui', function() { 12 cr.define("cr.ui",function(){function decorate(source,constr){var elements;if(ty peof source=="string")elements=cr.doc.querySelectorAll(source);else elements=[so urce];for(var i=0,el;el=elements[i];i++){if(!(el instanceof constr))constr.decor ate(el)}}function createElementHelper(tagName,opt_bag){var doc;if(opt_bag&&opt_b ag.ownerDocument)doc=opt_bag.ownerDocument;else doc=cr.doc;return doc.createElem ent(tagName)}function define(tagNameOrFunction){var createFunction,tagName;if(ty peof tagNameOrFunction=="function"){createFunction=tagNameOrFunction;tagName=""} else{createFunction=createElementHelper;tagName=tagNameOrFunction}function f(opt _propertyBag){var el=createFunction(tagName,opt_propertyBag);f.decorate(el);for( var propertyName in opt_propertyBag){el[propertyName]=opt_propertyBag[propertyNa me]}return el}f.decorate=function(el){el.__proto__=f.prototype;el.decorate()};re turn f}function limitInputWidth(el,parentEl,min,opt_scale){el.style.width="10px" ;var doc=el.ownerDocument;var win=doc.defaultView;var computedStyle=win.getCompu tedStyle(el);var parentComputedStyle=win.getComputedStyle(parentEl);var rtl=comp utedStyle.direction=="rtl";var inputRect=el.getBoundingClientRect();var parentRe ct=parentEl.getBoundingClientRect();var startPos=rtl?parentRect.right-inputRect. right:inputRect.left-parentRect.left;var inner=parseInt(computedStyle.borderLeft Width,10)+parseInt(computedStyle.paddingLeft,10)+parseInt(computedStyle.paddingR ight,10)+parseInt(computedStyle.borderRightWidth,10);var parentPadding=rtl?parse Int(parentComputedStyle.paddingLeft,10):parseInt(parentComputedStyle.paddingRigh t,10);var max=parentEl.clientWidth-startPos-inner-parentPadding;if(opt_scale)max *=opt_scale;function limit(){if(el.scrollWidth>max){el.style.width=max+"px"}else {el.style.width=0;var sw=el.scrollWidth;if(sw<min){el.style.width=min+"px"}else{ el.style.width=sw+"px"}}}el.addEventListener("input",limit);limit()}function toC ssPx(pixels){if(!window.isFinite(pixels))console.error("Pixel value is not a num ber: "+pixels);return Math.round(pixels)+"px"}function swallowDoubleClick(e){var doc=e.target.ownerDocument;var counter=Math.min(1,e.detail);function swallow(e) {e.stopPropagation();e.preventDefault()}function onclick(e){if(e.detail>counter) {counter=e.detail;swallow(e)}else{doc.removeEventListener("dblclick",swallow,tru e);doc.removeEventListener("click",onclick,true)}}setTimeout(function(){doc.addE ventListener("click",onclick,true);doc.addEventListener("dblclick",swallow,true) },0)}return{decorate:decorate,define:define,limitInputWidth:limitInputWidth,toCs sPx:toCssPx,swallowDoubleClick:swallowDoubleClick}});
259 function decorate(source, constr) {
260 var elements;
261 if (typeof source == 'string') elements = cr.doc.querySelectorAll(source); e lse elements = [ source ];
262 for (var i = 0, el; el = elements[i]; i++) {
263 if (!(el instanceof constr)) constr.decorate(el);
264 }
265 }
266 function createElementHelper(tagName, opt_bag) {
267 var doc;
268 if (opt_bag && opt_bag.ownerDocument) doc = opt_bag.ownerDocument; else doc = cr.doc;
269 return doc.createElement(tagName);
270 }
271 function define(tagNameOrFunction) {
272 var createFunction, tagName;
273 if (typeof tagNameOrFunction == 'function') {
274 createFunction = tagNameOrFunction;
275 tagName = '';
276 } else {
277 createFunction = createElementHelper;
278 tagName = tagNameOrFunction;
279 }
280 function f(opt_propertyBag) {
281 var el = createFunction(tagName, opt_propertyBag);
282 f.decorate(el);
283 for (var propertyName in opt_propertyBag) {
284 el[propertyName] = opt_propertyBag[propertyName];
285 }
286 return el;
287 }
288 f.decorate = function(el) {
289 el.__proto__ = f.prototype;
290 el.decorate();
291 };
292 return f;
293 }
294 function limitInputWidth(el, parentEl, min, opt_scale) {
295 el.style.width = '10px';
296 var doc = el.ownerDocument;
297 var win = doc.defaultView;
298 var computedStyle = win.getComputedStyle(el);
299 var parentComputedStyle = win.getComputedStyle(parentEl);
300 var rtl = computedStyle.direction == 'rtl';
301 var inputRect = el.getBoundingClientRect();
302 var parentRect = parentEl.getBoundingClientRect();
303 var startPos = rtl ? parentRect.right - inputRect.right : inputRect.left - p arentRect.left;
304 var inner = parseInt(computedStyle.borderLeftWidth, 10) + parseInt(computedS tyle.paddingLeft, 10) + parseInt(computedStyle.paddingRight, 10) + parseInt(comp utedStyle.borderRightWidth, 10);
305 var parentPadding = rtl ? parseInt(parentComputedStyle.paddingLeft, 10) : pa rseInt(parentComputedStyle.paddingRight, 10);
306 var max = parentEl.clientWidth - startPos - inner - parentPadding;
307 if (opt_scale) max *= opt_scale;
308 function limit() {
309 if (el.scrollWidth > max) {
310 el.style.width = max + 'px';
311 } else {
312 el.style.width = 0;
313 var sw = el.scrollWidth;
314 if (sw < min) {
315 el.style.width = min + 'px';
316 } else {
317 el.style.width = sw + 'px';
318 }
319 }
320 }
321 el.addEventListener('input', limit);
322 limit();
323 }
324 function toCssPx(pixels) {
325 if (!window.isFinite(pixels)) console.error('Pixel value is not a number: ' + pixels);
326 return Math.round(pixels) + 'px';
327 }
328 function swallowDoubleClick(e) {
329 var doc = e.target.ownerDocument;
330 var counter = Math.min(1, e.detail);
331 function swallow(e) {
332 e.stopPropagation();
333 e.preventDefault();
334 }
335 function onclick(e) {
336 if (e.detail > counter) {
337 counter = e.detail;
338 swallow(e);
339 } else {
340 doc.removeEventListener('dblclick', swallow, true);
341 doc.removeEventListener('click', onclick, true);
342 }
343 }
344 setTimeout(function() {
345 doc.addEventListener('click', onclick, true);
346 doc.addEventListener('dblclick', swallow, true);
347 }, 0);
348 }
349 return {
350 decorate: decorate,
351 define: define,
352 limitInputWidth: limitInputWidth,
353 toCssPx: toCssPx,
354 swallowDoubleClick: swallowDoubleClick
355 };
356 });
357
358 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 13 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
359 // Use of this source code is governed by a BSD-style license that can be 14 // Use of this source code is governed by a BSD-style license that can be
360 // found in the LICENSE file. 15 // found in the LICENSE file.
361 cr.define('cr.ui', function() { 16 cr.define("cr.ui",function(){function KeyboardShortcut(shortcut){var mods={};var ident="";shortcut.split("|").forEach(function(part){var partLc=part.toLowerCase ();switch(partLc){case"alt":case"ctrl":case"meta":case"shift":mods[partLc+"Key"] =true;break;default:if(ident)throw Error("Invalid shortcut");ident=part}});this. ident_=ident;this.mods_=mods}KeyboardShortcut.prototype={matchesEvent:function(e ){if(e.key==this.ident_){var mods=this.mods_;return["altKey","ctrlKey","metaKey" ,"shiftKey"].every(function(k){return e[k]==!!mods[k]})}return false}};var Comma nd=cr.ui.define("command");Command.prototype={__proto__:HTMLElement.prototype,de corate:function(){CommandManager.init(assert(this.ownerDocument));if(this.hasAtt ribute("shortcut"))this.shortcut=this.getAttribute("shortcut")},execute:function (opt_element){if(this.disabled)return;var doc=this.ownerDocument;if(doc.activeEl ement){var e=new Event("command",{bubbles:true});e.command=this;(opt_element||do c.activeElement).dispatchEvent(e)}},canExecuteChange:function(opt_node){dispatch CanExecuteEvent(this,opt_node||this.ownerDocument.activeElement)},shortcut_:"",g et shortcut(){return this.shortcut_},set shortcut(shortcut){var oldShortcut=this .shortcut_;if(shortcut!==oldShortcut){this.keyboardShortcuts_=shortcut.split(/\s +/).map(function(shortcut){return new KeyboardShortcut(shortcut)});this.shortcut _=shortcut;cr.dispatchPropertyChange(this,"shortcut",this.shortcut_,oldShortcut) }},matchesEvent:function(e){if(!this.keyboardShortcuts_)return false;return this .keyboardShortcuts_.some(function(keyboardShortcut){return keyboardShortcut.matc hesEvent(e)})}};cr.defineProperty(Command,"label",cr.PropertyKind.ATTR);cr.defin eProperty(Command,"disabled",cr.PropertyKind.BOOL_ATTR);cr.defineProperty(Comman d,"hidden",cr.PropertyKind.BOOL_ATTR);cr.defineProperty(Command,"checked",cr.Pro pertyKind.BOOL_ATTR);cr.defineProperty(Command,"hideShortcutText",cr.PropertyKin d.BOOL_ATTR);function dispatchCanExecuteEvent(command,target){var e=new CanExecu teEvent(command);target.dispatchEvent(e);command.disabled=!e.canExecute}var comm andManagers={};function CommandManager(doc){doc.addEventListener("focus",this.ha ndleFocus_.bind(this),true);doc.addEventListener("keydown",this.handleKeyDown_.b ind(this),false)}CommandManager.init=function(doc){var uid=cr.getUid(doc);if(!(u id in commandManagers)){commandManagers[uid]=new CommandManager(doc)}};CommandMa nager.prototype={handleFocus_:function(e){var target=e.target;if(target.menu||ta rget.command)return;var commands=Array.prototype.slice.call(target.ownerDocument .querySelectorAll("command"));commands.forEach(function(command){dispatchCanExec uteEvent(command,target)})},handleKeyDown_:function(e){var target=e.target;var c ommands=Array.prototype.slice.call(target.ownerDocument.querySelectorAll("comman d"));for(var i=0,command;command=commands[i];i++){if(command.matchesEvent(e)){co mmand.canExecuteChange();if(!command.disabled){e.preventDefault();e.stopPropagat ion();command.execute();return}}}}};function CanExecuteEvent(command){var e=new Event("canExecute",{bubbles:true,cancelable:true});e.__proto__=CanExecuteEvent.p rototype;e.command=command;return e}CanExecuteEvent.prototype={__proto__:Event.p rototype,command:null,canExecute_:false,get canExecute(){return this.canExecute_ },set canExecute(canExecute){this.canExecute_=!!canExecute;this.stopPropagation( );this.preventDefault()}};return{Command:Command,CanExecuteEvent:CanExecuteEvent }});Polymer({is:"iron-media-query",properties:{queryMatches:{type:Boolean,value: false,readOnly:true,notify:true},query:{type:String,observer:"queryChanged"},ful l:{type:Boolean,value:false},_boundMQHandler:{value:function(){return this.query Handler.bind(this)}},_mq:{value:null}},attached:function(){this.style.display="n one";this.queryChanged()},detached:function(){this._remove()},_add:function(){if (this._mq){this._mq.addListener(this._boundMQHandler)}},_remove:function(){if(th is._mq){this._mq.removeListener(this._boundMQHandler)}this._mq=null},queryChange d:function(){this._remove();var query=this.query;if(!query){return}if(!this.full &&query[0]!=="("){query="("+query+")"}this._mq=window.matchMedia(query);this._ad d();this.queryHandler(this._mq)},queryHandler:function(mq){this._setQueryMatches (mq.matches)}});Polymer.IronResizableBehavior={properties:{_parentResizable:{typ e:Object,observer:"_parentResizableChanged"},_notifyingDescendant:{type:Boolean, value:false}},listeners:{"iron-request-resize-notifications":"_onIronRequestResi zeNotifications"},created:function(){this._interestedResizables=[];this._boundNo tifyResize=this.notifyResize.bind(this)},attached:function(){this.fire("iron-req uest-resize-notifications",null,{node:this,bubbles:true,cancelable:true});if(!th is._parentResizable){window.addEventListener("resize",this._boundNotifyResize);t his.notifyResize()}},detached:function(){if(this._parentResizable){this._parentR esizable.stopResizeNotificationsFor(this)}else{window.removeEventListener("resiz e",this._boundNotifyResize)}this._parentResizable=null},notifyResize:function(){ if(!this.isAttached){return}this._interestedResizables.forEach(function(resizabl e){if(this.resizerShouldNotify(resizable)){this._notifyDescendant(resizable)}},t his);this._fireResize()},assignParentResizable:function(parentResizable){this._p arentResizable=parentResizable},stopResizeNotificationsFor:function(target){var index=this._interestedResizables.indexOf(target);if(index>-1){this._interestedRe sizables.splice(index,1);this.unlisten(target,"iron-resize","_onDescendantIronRe size")}},resizerShouldNotify:function(element){return true},_onDescendantIronRes ize:function(event){if(this._notifyingDescendant){event.stopPropagation();return }if(!Polymer.Settings.useShadow){this._fireResize()}},_fireResize:function(){thi s.fire("iron-resize",null,{node:this,bubbles:false})},_onIronRequestResizeNotifi cations:function(event){var target=event.path?event.path[0]:event.target;if(targ et===this){return}if(this._interestedResizables.indexOf(target)===-1){this._inte restedResizables.push(target);this.listen(target,"iron-resize","_onDescendantIro nResize")}target.assignParentResizable(this);this._notifyDescendant(target);even t.stopPropagation()},_parentResizableChanged:function(parentResizable){if(parent Resizable){window.removeEventListener("resize",this._boundNotifyResize)}},_notif yDescendant:function(descendant){if(!this.isAttached){return}this._notifyingDesc endant=true;descendant.notifyResize();this._notifyingDescendant=false}};Polymer. IronSelection=function(selectCallback){this.selection=[];this.selectCallback=sel ectCallback};Polymer.IronSelection.prototype={get:function(){return this.multi?t his.selection.slice():this.selection[0]},clear:function(excludes){this.selection .slice().forEach(function(item){if(!excludes||excludes.indexOf(item)<0){this.set ItemSelected(item,false)}},this)},isSelected:function(item){return this.selectio n.indexOf(item)>=0},setItemSelected:function(item,isSelected){if(item!=null){if( isSelected!==this.isSelected(item)){if(isSelected){this.selection.push(item)}els e{var i=this.selection.indexOf(item);if(i>=0){this.selection.splice(i,1)}}if(thi s.selectCallback){this.selectCallback(item,isSelected)}}}},select:function(item) {if(this.multi){this.toggle(item)}else if(this.get()!==item){this.setItemSelecte d(this.get(),false);this.setItemSelected(item,true)}},toggle:function(item){this .setItemSelected(item,!this.isSelected(item))}};Polymer.IronSelectableBehavior={ properties:{attrForSelected:{type:String,value:null},selected:{type:String,notif y:true},selectedItem:{type:Object,readOnly:true,notify:true},activateEvent:{type :String,value:"tap",observer:"_activateEventChanged"},selectable:String,selected Class:{type:String,value:"iron-selected"},selectedAttribute:{type:String,value:n ull},fallbackSelection:{type:String,value:null},items:{type:Array,readOnly:true, notify:true,value:function(){return[]}},_excludedLocalNames:{type:Object,value:f unction(){return{template:1}}}},observers:["_updateAttrForSelected(attrForSelect ed)","_updateSelected(selected)","_checkFallback(fallbackSelection)"],created:fu nction(){this._bindFilterItem=this._filterItem.bind(this);this._selection=new Po lymer.IronSelection(this._applySelection.bind(this))},attached:function(){this._ observer=this._observeItems(this);this._updateItems();if(!this._shouldUpdateSele ction){this._updateSelected()}this._addListener(this.activateEvent)},detached:fu nction(){if(this._observer){Polymer.dom(this).unobserveNodes(this._observer)}thi s._removeListener(this.activateEvent)},indexOf:function(item){return this.items. indexOf(item)},select:function(value){this.selected=value},selectPrevious:functi on(){var length=this.items.length;var index=(Number(this._valueToIndex(this.sele cted))-1+length)%length;this.selected=this._indexToValue(index)},selectNext:func tion(){var index=(Number(this._valueToIndex(this.selected))+1)%this.items.length ;this.selected=this._indexToValue(index)},selectIndex:function(index){this.selec t(this._indexToValue(index))},forceSynchronousItemUpdate:function(){this._update Items()},get _shouldUpdateSelection(){return this.selected!=null},_checkFallback :function(){if(this._shouldUpdateSelection){this._updateSelected()}},_addListene r:function(eventName){this.listen(this,eventName,"_activateHandler")},_removeLis tener:function(eventName){this.unlisten(this,eventName,"_activateHandler")},_act ivateEventChanged:function(eventName,old){this._removeListener(old);this._addLis tener(eventName)},_updateItems:function(){var nodes=Polymer.dom(this).queryDistr ibutedElements(this.selectable||"*");nodes=Array.prototype.filter.call(nodes,thi s._bindFilterItem);this._setItems(nodes)},_updateAttrForSelected:function(){if(t his._shouldUpdateSelection){this.selected=this._indexToValue(this.indexOf(this.s electedItem))}},_updateSelected:function(){this._selectSelected(this.selected)}, _selectSelected:function(selected){this._selection.select(this._valueToItem(this .selected));if(this.fallbackSelection&&this.items.length&&this._selection.get()= ==undefined){this.selected=this.fallbackSelection}},_filterItem:function(node){r eturn!this._excludedLocalNames[node.localName]},_valueToItem:function(value){ret urn value==null?null:this.items[this._valueToIndex(value)]},_valueToIndex:functi on(value){if(this.attrForSelected){for(var i=0,item;item=this.items[i];i++){if(t his._valueForItem(item)==value){return i}}}else{return Number(value)}},_indexToV alue:function(index){if(this.attrForSelected){var item=this.items[index];if(item ){return this._valueForItem(item)}}else{return index}},_valueForItem:function(it em){var propValue=item[Polymer.CaseMap.dashToCamelCase(this.attrForSelected)];re turn propValue!=undefined?propValue:item.getAttribute(this.attrForSelected)},_ap plySelection:function(item,isSelected){if(this.selectedClass){this.toggleClass(t his.selectedClass,isSelected,item)}if(this.selectedAttribute){this.toggleAttribu te(this.selectedAttribute,isSelected,item)}this._selectionChange();this.fire("ir on-"+(isSelected?"select":"deselect"),{item:item})},_selectionChange:function(){ this._setSelectedItem(this._selection.get())},_observeItems:function(node){retur n Polymer.dom(node).observeNodes(function(mutation){this._updateItems();if(this. _shouldUpdateSelection){this._updateSelected()}this.fire("iron-items-changed",mu tation,{bubbles:false,cancelable:false})})},_activateHandler:function(e){var t=e .target;var items=this.items;while(t&&t!=this){var i=items.indexOf(t);if(i>=0){v ar value=this._indexToValue(i);this._itemActivate(value,t);return}t=t.parentNode }},_itemActivate:function(value,item){if(!this.fire("iron-activate",{selected:va lue,item:item},{cancelable:true}).defaultPrevented){this.select(value)}}};Polyme r({is:"iron-pages",behaviors:[Polymer.IronResizableBehavior,Polymer.IronSelectab leBehavior],properties:{activateEvent:{type:String,value:null}},observers:["_sel ectedPageChanged(selected)"],_selectedPageChanged:function(selected,old){this.as ync(this.notifyResize)}});Polymer.IronScrollTargetBehavior={properties:{scrollTa rget:{type:HTMLElement,value:function(){return this._defaultScrollTarget}}},obse rvers:["_scrollTargetChanged(scrollTarget, isAttached)"],_scrollTargetChanged:fu nction(scrollTarget,isAttached){var eventTarget;if(this._oldScrollTarget){eventT arget=this._oldScrollTarget===this._doc?window:this._oldScrollTarget;eventTarget .removeEventListener("scroll",this._boundScrollHandler);this._oldScrollTarget=nu ll}if(!isAttached){return}if(scrollTarget==="document"){this.scrollTarget=this._ doc}else if(typeof scrollTarget==="string"){this.scrollTarget=this.domHost?this. domHost.$[scrollTarget]:Polymer.dom(this.ownerDocument).querySelector("#"+scroll Target)}else if(this._isValidScrollTarget()){eventTarget=scrollTarget===this._do c?window:scrollTarget;this._boundScrollHandler=this._boundScrollHandler||this._s crollHandler.bind(this);this._oldScrollTarget=scrollTarget;eventTarget.addEventL istener("scroll",this._boundScrollHandler)}},_scrollHandler:function scrollHandl er(){},get _defaultScrollTarget(){return this._doc},get _doc(){return this.owner Document.documentElement},get _scrollTop(){if(this._isValidScrollTarget()){retur n this.scrollTarget===this._doc?window.pageYOffset:this.scrollTarget.scrollTop}r eturn 0},get _scrollLeft(){if(this._isValidScrollTarget()){return this.scrollTar get===this._doc?window.pageXOffset:this.scrollTarget.scrollLeft}return 0},set _s crollTop(top){if(this.scrollTarget===this._doc){window.scrollTo(window.pageXOffs et,top)}else if(this._isValidScrollTarget()){this.scrollTarget.scrollTop=top}},s et _scrollLeft(left){if(this.scrollTarget===this._doc){window.scrollTo(left,wind ow.pageYOffset)}else if(this._isValidScrollTarget()){this.scrollTarget.scrollLef t=left}},scroll:function(left,top){if(this.scrollTarget===this._doc){window.scro llTo(left,top)}else if(this._isValidScrollTarget()){this.scrollTarget.scrollLeft =left;this.scrollTarget.scrollTop=top}},get _scrollTargetWidth(){if(this._isVali dScrollTarget()){return this.scrollTarget===this._doc?window.innerWidth:this.scr ollTarget.offsetWidth}return 0},get _scrollTargetHeight(){if(this._isValidScroll Target()){return this.scrollTarget===this._doc?window.innerHeight:this.scrollTar get.offsetHeight}return 0},_isValidScrollTarget:function(){return this.scrollTar get instanceof HTMLElement}};(function(){var metaDatas={};var metaArrays={};var singleton=null;Polymer.IronMeta=Polymer({is:"iron-meta",properties:{type:{type:S tring,value:"default",observer:"_typeChanged"},key:{type:String,observer:"_keyCh anged"},value:{type:Object,notify:true,observer:"_valueChanged"},self:{type:Bool ean,observer:"_selfChanged"},list:{type:Array,notify:true}},hostAttributes:{hidd en:true},factoryImpl:function(config){if(config){for(var n in config){switch(n){ case"type":case"key":case"value":this[n]=config[n];break}}}},created:function(){ this._metaDatas=metaDatas;this._metaArrays=metaArrays},_keyChanged:function(key, old){this._resetRegistration(old)},_valueChanged:function(value){this._resetRegi stration(this.key)},_selfChanged:function(self){if(self){this.value=this}},_type Changed:function(type){this._unregisterKey(this.key);if(!metaDatas[type]){metaDa tas[type]={}}this._metaData=metaDatas[type];if(!metaArrays[type]){metaArrays[typ e]=[]}this.list=metaArrays[type];this._registerKeyValue(this.key,this.value)},by Key:function(key){return this._metaData&&this._metaData[key]},_resetRegistration :function(oldKey){this._unregisterKey(oldKey);this._registerKeyValue(this.key,th is.value)},_unregisterKey:function(key){this._unregister(key,this._metaData,this .list)},_registerKeyValue:function(key,value){this._register(key,value,this._met aData,this.list)},_register:function(key,value,data,list){if(key&&data&&value!== undefined){data[key]=value;list.push(value)}},_unregister:function(key,data,list ){if(key&&data){if(key in data){var value=data[key];delete data[key];this.arrayD elete(list,value)}}}});Polymer.IronMeta.getIronMeta=function getIronMeta(){if(si ngleton===null){singleton=new Polymer.IronMeta}return singleton};Polymer.IronMet aQuery=Polymer({is:"iron-meta-query",properties:{type:{type:String,value:"defaul t",observer:"_typeChanged"},key:{type:String,observer:"_keyChanged"},value:{type :Object,notify:true,readOnly:true},list:{type:Array,notify:true}},factoryImpl:fu nction(config){if(config){for(var n in config){switch(n){case"type":case"key":th is[n]=config[n];break}}}},created:function(){this._metaDatas=metaDatas;this._met aArrays=metaArrays},_keyChanged:function(key){this._setValue(this._metaData&&thi s._metaData[key])},_typeChanged:function(type){this._metaData=metaDatas[type];th is.list=metaArrays[type];if(this.key){this._keyChanged(this.key)}},byKey:functio n(key){return this._metaData&&this._metaData[key]}})})();Polymer({is:"iron-icon" ,properties:{icon:{type:String,observer:"_iconChanged"},theme:{type:String,obser ver:"_updateIcon"},src:{type:String,observer:"_srcChanged"},_meta:{value:Polymer .Base.create("iron-meta",{type:"iconset"}),observer:"_updateIcon"}},_DEFAULT_ICO NSET:"icons",_iconChanged:function(icon){var parts=(icon||"").split(":");this._i conName=parts.pop();this._iconsetName=parts.pop()||this._DEFAULT_ICONSET;this._u pdateIcon()},_srcChanged:function(src){this._updateIcon()},_usesIconset:function (){return this.icon||!this.src},_updateIcon:function(){if(this._usesIconset()){i f(this._img&&this._img.parentNode){Polymer.dom(this.root).removeChild(this._img) }if(this._iconName===""){if(this._iconset){this._iconset.removeIcon(this)}}else if(this._iconsetName&&this._meta){this._iconset=this._meta.byKey(this._iconsetNa me);if(this._iconset){this._iconset.applyIcon(this,this._iconName,this.theme);th is.unlisten(window,"iron-iconset-added","_updateIcon")}else{this.listen(window," iron-iconset-added","_updateIcon")}}}else{if(this._iconset){this._iconset.remove Icon(this)}if(!this._img){this._img=document.createElement("img");this._img.styl e.width="100%";this._img.style.height="100%";this._img.draggable=false}this._img .src=this.src;Polymer.dom(this.root).appendChild(this._img)}}});(function(){"use strict";var KEY_IDENTIFIER={"U+0008":"backspace","U+0009":"tab","U+001B":"esc", "U+0020":"space","U+007F":"del"};var KEY_CODE={8:"backspace",9:"tab",13:"enter", 27:"esc",33:"pageup",34:"pagedown",35:"end",36:"home",32:"space",37:"left",38:"u p",39:"right",40:"down",46:"del",106:"*"};var MODIFIER_KEYS={shift:"shiftKey",ct rl:"ctrlKey",alt:"altKey",meta:"metaKey"};var KEY_CHAR=/[a-z0-9*]/;var IDENT_CHA R=/U\+/;var ARROW_KEY=/^arrow/;var SPACE_KEY=/^space(bar)?/;var ESC_KEY=/^escape $/;function transformKey(key,noSpecialChars){var validKey="";if(key){var lKey=ke y.toLowerCase();if(lKey===" "||SPACE_KEY.test(lKey)){validKey="space"}else if(ES C_KEY.test(lKey)){validKey="esc"}else if(lKey.length==1){if(!noSpecialChars||KEY _CHAR.test(lKey)){validKey=lKey}}else if(ARROW_KEY.test(lKey)){validKey=lKey.rep lace("arrow","")}else if(lKey=="multiply"){validKey="*"}else{validKey=lKey}}retu rn validKey}function transformKeyIdentifier(keyIdent){var validKey="";if(keyIden t){if(keyIdent in KEY_IDENTIFIER){validKey=KEY_IDENTIFIER[keyIdent]}else if(IDEN T_CHAR.test(keyIdent)){keyIdent=parseInt(keyIdent.replace("U+","0x"),16);validKe y=String.fromCharCode(keyIdent).toLowerCase()}else{validKey=keyIdent.toLowerCase ()}}return validKey}function transformKeyCode(keyCode){var validKey="";if(Number (keyCode)){if(keyCode>=65&&keyCode<=90){validKey=String.fromCharCode(32+keyCode) }else if(keyCode>=112&&keyCode<=123){validKey="f"+(keyCode-112)}else if(keyCode> =48&&keyCode<=57){validKey=String(keyCode-48)}else if(keyCode>=96&&keyCode<=105) {validKey=String(keyCode-96)}else{validKey=KEY_CODE[keyCode]}}return validKey}fu nction normalizedKeyForEvent(keyEvent,noSpecialChars){if(keyEvent.key){return tr ansformKey(keyEvent.key,noSpecialChars)}if(keyEvent.detail&&keyEvent.detail.key) {return transformKey(keyEvent.detail.key,noSpecialChars)}return transformKeyIden tifier(keyEvent.keyIdentifier)||transformKeyCode(keyEvent.keyCode)||""}function keyComboMatchesEvent(keyCombo,event){var keyEvent=normalizedKeyForEvent(event,ke yCombo.hasModifiers);return keyEvent===keyCombo.key&&(!keyCombo.hasModifiers||!! event.shiftKey===!!keyCombo.shiftKey&&!!event.ctrlKey===!!keyCombo.ctrlKey&&!!ev ent.altKey===!!keyCombo.altKey&&!!event.metaKey===!!keyCombo.metaKey)}function p arseKeyComboString(keyComboString){if(keyComboString.length===1){return{combo:ke yComboString,key:keyComboString,event:"keydown"}}return keyComboString.split("+" ).reduce(function(parsedKeyCombo,keyComboPart){var eventParts=keyComboPart.split (":");var keyName=eventParts[0];var event=eventParts[1];if(keyName in MODIFIER_K EYS){parsedKeyCombo[MODIFIER_KEYS[keyName]]=true;parsedKeyCombo.hasModifiers=tru e}else{parsedKeyCombo.key=keyName;parsedKeyCombo.event=event||"keydown"}return p arsedKeyCombo},{combo:keyComboString.split(":").shift()})}function parseEventStr ing(eventString){return eventString.trim().split(" ").map(function(keyComboStrin g){return parseKeyComboString(keyComboString)})}Polymer.IronA11yKeysBehavior={pr operties:{keyEventTarget:{type:Object,value:function(){return this}},stopKeyboar dEventPropagation:{type:Boolean,value:false},_boundKeyHandlers:{type:Array,value :function(){return[]}},_imperativeKeyBindings:{type:Object,value:function(){retu rn{}}}},observers:["_resetKeyEventListeners(keyEventTarget, _boundKeyHandlers)"] ,keyBindings:{},registered:function(){this._prepKeyBindings()},attached:function (){this._listenKeyEventListeners()},detached:function(){this._unlistenKeyEventLi steners()},addOwnKeyBinding:function(eventString,handlerName){this._imperativeKe yBindings[eventString]=handlerName;this._prepKeyBindings();this._resetKeyEventLi steners()},removeOwnKeyBindings:function(){this._imperativeKeyBindings={};this._ prepKeyBindings();this._resetKeyEventListeners()},keyboardEventMatchesKeys:funct ion(event,eventString){var keyCombos=parseEventString(eventString);for(var i=0;i <keyCombos.length;++i){if(keyComboMatchesEvent(keyCombos[i],event)){return true} }return false},_collectKeyBindings:function(){var keyBindings=this.behaviors.map (function(behavior){return behavior.keyBindings});if(keyBindings.indexOf(this.ke yBindings)===-1){keyBindings.push(this.keyBindings)}return keyBindings},_prepKey Bindings:function(){this._keyBindings={};this._collectKeyBindings().forEach(func tion(keyBindings){for(var eventString in keyBindings){this._addKeyBinding(eventS tring,keyBindings[eventString])}},this);for(var eventString in this._imperativeK eyBindings){this._addKeyBinding(eventString,this._imperativeKeyBindings[eventStr ing])}for(var eventName in this._keyBindings){this._keyBindings[eventName].sort( function(kb1,kb2){var b1=kb1[0].hasModifiers;var b2=kb2[0].hasModifiers;return b 1===b2?0:b1?-1:1})}},_addKeyBinding:function(eventString,handlerName){parseEvent String(eventString).forEach(function(keyCombo){this._keyBindings[keyCombo.event] =this._keyBindings[keyCombo.event]||[];this._keyBindings[keyCombo.event].push([k eyCombo,handlerName])},this)},_resetKeyEventListeners:function(){this._unlistenK eyEventListeners();if(this.isAttached){this._listenKeyEventListeners()}},_listen KeyEventListeners:function(){if(!this.keyEventTarget){return}Object.keys(this._k eyBindings).forEach(function(eventName){var keyBindings=this._keyBindings[eventN ame];var boundKeyHandler=this._onKeyBindingEvent.bind(this,keyBindings);this._bo undKeyHandlers.push([this.keyEventTarget,eventName,boundKeyHandler]);this.keyEve ntTarget.addEventListener(eventName,boundKeyHandler)},this)},_unlistenKeyEventLi steners:function(){var keyHandlerTuple;var keyEventTarget;var eventName;var boun dKeyHandler;while(this._boundKeyHandlers.length){keyHandlerTuple=this._boundKeyH andlers.pop();keyEventTarget=keyHandlerTuple[0];eventName=keyHandlerTuple[1];bou ndKeyHandler=keyHandlerTuple[2];keyEventTarget.removeEventListener(eventName,bou ndKeyHandler)}},_onKeyBindingEvent:function(keyBindings,event){if(this.stopKeybo ardEventPropagation){event.stopPropagation()}if(event.defaultPrevented){return}f or(var i=0;i<keyBindings.length;i++){var keyCombo=keyBindings[i][0];var handlerN ame=keyBindings[i][1];if(keyComboMatchesEvent(keyCombo,event)){this._triggerKeyH andler(keyCombo,handlerName,event);if(event.defaultPrevented){return}}}},_trigge rKeyHandler:function(keyCombo,handlerName,keyboardEvent){var detail=Object.creat e(keyCombo);detail.keyboardEvent=keyboardEvent;var event=new CustomEvent(keyComb o.event,{detail:detail,cancelable:true});this[handlerName].call(this,event);if(e vent.defaultPrevented){keyboardEvent.preventDefault()}}}})();Polymer.IronControl State={properties:{focused:{type:Boolean,value:false,notify:true,readOnly:true,r eflectToAttribute:true},disabled:{type:Boolean,value:false,notify:true,observer: "_disabledChanged",reflectToAttribute:true},_oldTabIndex:{type:Number},_boundFoc usBlurHandler:{type:Function,value:function(){return this._focusBlurHandler.bind (this)}}},observers:["_changedControlState(focused, disabled)"],ready:function() {this.addEventListener("focus",this._boundFocusBlurHandler,true);this.addEventLi stener("blur",this._boundFocusBlurHandler,true)},_focusBlurHandler:function(even t){if(event.target===this){this._setFocused(event.type==="focus")}else if(!this. shadowRoot){var target=Polymer.dom(event).localTarget;if(!this.isLightDescendant (target)){this.fire(event.type,{sourceEvent:event},{node:this,bubbles:event.bubb les,cancelable:event.cancelable})}}},_disabledChanged:function(disabled,old){thi s.setAttribute("aria-disabled",disabled?"true":"false");this.style.pointerEvents =disabled?"none":"";if(disabled){this._oldTabIndex=this.tabIndex;this._setFocuse d(false);this.tabIndex=-1;this.blur()}else if(this._oldTabIndex!==undefined){thi s.tabIndex=this._oldTabIndex}},_changedControlState:function(){if(this._controlS tateChanged){this._controlStateChanged()}}};Polymer.IronButtonStateImpl={propert ies:{pressed:{type:Boolean,readOnly:true,value:false,reflectToAttribute:true,obs erver:"_pressedChanged"},toggles:{type:Boolean,value:false,reflectToAttribute:tr ue},active:{type:Boolean,value:false,notify:true,reflectToAttribute:true},pointe rDown:{type:Boolean,readOnly:true,value:false},receivedFocusFromKeyboard:{type:B oolean,readOnly:true},ariaActiveAttribute:{type:String,value:"aria-pressed",obse rver:"_ariaActiveAttributeChanged"}},listeners:{down:"_downHandler",up:"_upHandl er",tap:"_tapHandler"},observers:["_detectKeyboardFocus(focused)","_activeChange d(active, ariaActiveAttribute)"],keyBindings:{"enter:keydown":"_asyncClick","spa ce:keydown":"_spaceKeyDownHandler","space:keyup":"_spaceKeyUpHandler"},_mouseEve ntRe:/^mouse/,_tapHandler:function(){if(this.toggles){this._userActivate(!this.a ctive)}else{this.active=false}},_detectKeyboardFocus:function(focused){this._set ReceivedFocusFromKeyboard(!this.pointerDown&&focused)},_userActivate:function(ac tive){if(this.active!==active){this.active=active;this.fire("change")}},_downHan dler:function(event){this._setPointerDown(true);this._setPressed(true);this._set ReceivedFocusFromKeyboard(false)},_upHandler:function(){this._setPointerDown(fal se);this._setPressed(false)},_spaceKeyDownHandler:function(event){var keyboardEv ent=event.detail.keyboardEvent;var target=Polymer.dom(keyboardEvent).localTarget ;if(this.isLightDescendant(target))return;keyboardEvent.preventDefault();keyboar dEvent.stopImmediatePropagation();this._setPressed(true)},_spaceKeyUpHandler:fun ction(event){var keyboardEvent=event.detail.keyboardEvent;var target=Polymer.dom (keyboardEvent).localTarget;if(this.isLightDescendant(target))return;if(this.pre ssed){this._asyncClick()}this._setPressed(false)},_asyncClick:function(){this.as ync(function(){this.click()},1)},_pressedChanged:function(pressed){this._changed ButtonState()},_ariaActiveAttributeChanged:function(value,oldValue){if(oldValue& &oldValue!=value&&this.hasAttribute(oldValue)){this.removeAttribute(oldValue)}}, _activeChanged:function(active,ariaActiveAttribute){if(this.toggles){this.setAtt ribute(this.ariaActiveAttribute,active?"true":"false")}else{this.removeAttribute (this.ariaActiveAttribute)}this._changedButtonState()},_controlStateChanged:func tion(){if(this.disabled){this._setPressed(false)}else{this._changedButtonState() }},_changedButtonState:function(){if(this._buttonStateChanged){this._buttonState Changed()}}};Polymer.IronButtonState=[Polymer.IronA11yKeysBehavior,Polymer.IronB uttonStateImpl];(function(){var Utility={distance:function(x1,y1,x2,y2){var xDel ta=x1-x2;var yDelta=y1-y2;return Math.sqrt(xDelta*xDelta+yDelta*yDelta)},now:win dow.performance&&window.performance.now?window.performance.now.bind(window.perfo rmance):Date.now};function ElementMetrics(element){this.element=element;this.wid th=this.boundingRect.width;this.height=this.boundingRect.height;this.size=Math.m ax(this.width,this.height)}ElementMetrics.prototype={get boundingRect(){return t his.element.getBoundingClientRect()},furthestCornerDistanceFrom:function(x,y){va r topLeft=Utility.distance(x,y,0,0);var topRight=Utility.distance(x,y,this.width ,0);var bottomLeft=Utility.distance(x,y,0,this.height);var bottomRight=Utility.d istance(x,y,this.width,this.height);return Math.max(topLeft,topRight,bottomLeft, bottomRight)}};function Ripple(element){this.element=element;this.color=window.g etComputedStyle(element).color;this.wave=document.createElement("div");this.wave Container=document.createElement("div");this.wave.style.backgroundColor=this.col or;this.wave.classList.add("wave");this.waveContainer.classList.add("wave-contai ner");Polymer.dom(this.waveContainer).appendChild(this.wave);this.resetInteracti onState()}Ripple.MAX_RADIUS=300;Ripple.prototype={get recenters(){return this.el ement.recenters},get center(){return this.element.center},get mouseDownElapsed() {var elapsed;if(!this.mouseDownStart){return 0}elapsed=Utility.now()-this.mouseD ownStart;if(this.mouseUpStart){elapsed-=this.mouseUpElapsed}return elapsed},get mouseUpElapsed(){return this.mouseUpStart?Utility.now()-this.mouseUpStart:0},get mouseDownElapsedSeconds(){return this.mouseDownElapsed/1e3},get mouseUpElapsedS econds(){return this.mouseUpElapsed/1e3},get mouseInteractionSeconds(){return th is.mouseDownElapsedSeconds+this.mouseUpElapsedSeconds},get initialOpacity(){retu rn this.element.initialOpacity},get opacityDecayVelocity(){return this.element.o pacityDecayVelocity},get radius(){var width2=this.containerMetrics.width*this.co ntainerMetrics.width;var height2=this.containerMetrics.height*this.containerMetr ics.height;var waveRadius=Math.min(Math.sqrt(width2+height2),Ripple.MAX_RADIUS)* 1.1+5;var duration=1.1-.2*(waveRadius/Ripple.MAX_RADIUS);var timeNow=this.mouseI nteractionSeconds/duration;var size=waveRadius*(1-Math.pow(80,-timeNow));return Math.abs(size)},get opacity(){if(!this.mouseUpStart){return this.initialOpacity} return Math.max(0,this.initialOpacity-this.mouseUpElapsedSeconds*this.opacityDec ayVelocity)},get outerOpacity(){var outerOpacity=this.mouseUpElapsedSeconds*.3;v ar waveOpacity=this.opacity;return Math.max(0,Math.min(outerOpacity,waveOpacity) )},get isOpacityFullyDecayed(){return this.opacity<.01&&this.radius>=Math.min(th is.maxRadius,Ripple.MAX_RADIUS)},get isRestingAtMaxRadius(){return this.opacity> =this.initialOpacity&&this.radius>=Math.min(this.maxRadius,Ripple.MAX_RADIUS)},g et isAnimationComplete(){return this.mouseUpStart?this.isOpacityFullyDecayed:thi s.isRestingAtMaxRadius},get translationFraction(){return Math.min(1,this.radius/ this.containerMetrics.size*2/Math.sqrt(2))},get xNow(){if(this.xEnd){return this .xStart+this.translationFraction*(this.xEnd-this.xStart)}return this.xStart},get yNow(){if(this.yEnd){return this.yStart+this.translationFraction*(this.yEnd-thi s.yStart)}return this.yStart},get isMouseDown(){return this.mouseDownStart&&!thi s.mouseUpStart},resetInteractionState:function(){this.maxRadius=0;this.mouseDown Start=0;this.mouseUpStart=0;this.xStart=0;this.yStart=0;this.xEnd=0;this.yEnd=0; this.slideDistance=0;this.containerMetrics=new ElementMetrics(this.element)},dra w:function(){var scale;var translateString;var dx;var dy;this.wave.style.opacity =this.opacity;scale=this.radius/(this.containerMetrics.size/2);dx=this.xNow-this .containerMetrics.width/2;
362 function KeyboardShortcut(shortcut) {
363 var mods = {};
364 var ident = '';
365 shortcut.split('|').forEach(function(part) {
366 var partLc = part.toLowerCase();
367 switch (partLc) {
368 case 'alt':
369 case 'ctrl':
370 case 'meta':
371 case 'shift':
372 mods[partLc + 'Key'] = true;
373 break;
374 17
375 default: 18 dy=this.yNow-this.containerMetrics.height/2;this.waveContainer.style.webkitTrans form="translate("+dx+"px, "+dy+"px)";this.waveContainer.style.transform="transla te3d("+dx+"px, "+dy+"px, 0)";this.wave.style.webkitTransform="scale("+scale+","+ scale+")";this.wave.style.transform="scale3d("+scale+","+scale+",1)"},downAction :function(event){var xCenter=this.containerMetrics.width/2;var yCenter=this.cont ainerMetrics.height/2;this.resetInteractionState();this.mouseDownStart=Utility.n ow();if(this.center){this.xStart=xCenter;this.yStart=yCenter;this.slideDistance= Utility.distance(this.xStart,this.yStart,this.xEnd,this.yEnd)}else{this.xStart=e vent?event.detail.x-this.containerMetrics.boundingRect.left:this.containerMetric s.width/2;this.yStart=event?event.detail.y-this.containerMetrics.boundingRect.to p:this.containerMetrics.height/2}if(this.recenters){this.xEnd=xCenter;this.yEnd= yCenter;this.slideDistance=Utility.distance(this.xStart,this.yStart,this.xEnd,th is.yEnd)}this.maxRadius=this.containerMetrics.furthestCornerDistanceFrom(this.xS tart,this.yStart);this.waveContainer.style.top=(this.containerMetrics.height-thi s.containerMetrics.size)/2+"px";this.waveContainer.style.left=(this.containerMet rics.width-this.containerMetrics.size)/2+"px";this.waveContainer.style.width=thi s.containerMetrics.size+"px";this.waveContainer.style.height=this.containerMetri cs.size+"px"},upAction:function(event){if(!this.isMouseDown){return}this.mouseUp Start=Utility.now()},remove:function(){Polymer.dom(this.waveContainer.parentNode ).removeChild(this.waveContainer)}};Polymer({is:"paper-ripple",behaviors:[Polyme r.IronA11yKeysBehavior],properties:{initialOpacity:{type:Number,value:.25},opaci tyDecayVelocity:{type:Number,value:.8},recenters:{type:Boolean,value:false},cent er:{type:Boolean,value:false},ripples:{type:Array,value:function(){return[]}},an imating:{type:Boolean,readOnly:true,reflectToAttribute:true,value:false},holdDow n:{type:Boolean,value:false,observer:"_holdDownChanged"},noink:{type:Boolean,val ue:false},_animating:{type:Boolean},_boundAnimate:{type:Function,value:function( ){return this.animate.bind(this)}}},get target(){return this.keyEventTarget},key Bindings:{"enter:keydown":"_onEnterKeydown","space:keydown":"_onSpaceKeydown","s pace:keyup":"_onSpaceKeyup"},attached:function(){if(this.parentNode.nodeType==11 ){this.keyEventTarget=Polymer.dom(this).getOwnerRoot().host}else{this.keyEventTa rget=this.parentNode}var keyEventTarget=this.keyEventTarget;this.listen(keyEvent Target,"up","uiUpAction");this.listen(keyEventTarget,"down","uiDownAction")},det ached:function(){this.unlisten(this.keyEventTarget,"up","uiUpAction");this.unlis ten(this.keyEventTarget,"down","uiDownAction");this.keyEventTarget=null},get sho uldKeepAnimating(){for(var index=0;index<this.ripples.length;++index){if(!this.r ipples[index].isAnimationComplete){return true}}return false},simulatedRipple:fu nction(){this.downAction(null);this.async(function(){this.upAction()},1)},uiDown Action:function(event){if(!this.noink){this.downAction(event)}},downAction:funct ion(event){if(this.holdDown&&this.ripples.length>0){return}var ripple=this.addRi pple();ripple.downAction(event);if(!this._animating){this._animating=true;this.a nimate()}},uiUpAction:function(event){if(!this.noink){this.upAction(event)}},upA ction:function(event){if(this.holdDown){return}this.ripples.forEach(function(rip ple){ripple.upAction(event)});this._animating=true;this.animate()},onAnimationCo mplete:function(){this._animating=false;this.$.background.style.backgroundColor= null;this.fire("transitionend")},addRipple:function(){var ripple=new Ripple(this );Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);this.$.background. style.backgroundColor=ripple.color;this.ripples.push(ripple);this._setAnimating( true);return ripple},removeRipple:function(ripple){var rippleIndex=this.ripples. indexOf(ripple);if(rippleIndex<0){return}this.ripples.splice(rippleIndex,1);ripp le.remove();if(!this.ripples.length){this._setAnimating(false)}},animate:functio n(){if(!this._animating){return}var index;var ripple;for(index=0;index<this.ripp les.length;++index){ripple=this.ripples[index];ripple.draw();this.$.background.s tyle.opacity=ripple.outerOpacity;if(ripple.isOpacityFullyDecayed&&!ripple.isRest ingAtMaxRadius){this.removeRipple(ripple)}}if(!this.shouldKeepAnimating&&this.ri pples.length===0){this.onAnimationComplete()}else{window.requestAnimationFrame(t his._boundAnimate)}},_onEnterKeydown:function(){this.uiDownAction();this.async(t his.uiUpAction,1)},_onSpaceKeydown:function(){this.uiDownAction()},_onSpaceKeyup :function(){this.uiUpAction()},_holdDownChanged:function(newVal,oldVal){if(oldVa l===undefined){return}if(newVal){this.downAction()}else{this.upAction()}}})})(); Polymer.PaperRippleBehavior={properties:{noink:{type:Boolean,observer:"_noinkCha nged"},_rippleContainer:{type:Object}},_buttonStateChanged:function(){if(this.fo cused){this.ensureRipple()}},_downHandler:function(event){Polymer.IronButtonStat eImpl._downHandler.call(this,event);if(this.pressed){this.ensureRipple(event)}}, ensureRipple:function(optTriggeringEvent){if(!this.hasRipple()){this._ripple=thi s._createRipple();this._ripple.noink=this.noink;var rippleContainer=this._ripple Container||this.root;if(rippleContainer){Polymer.dom(rippleContainer).appendChil d(this._ripple)}if(optTriggeringEvent){var domContainer=Polymer.dom(this._ripple Container||this);var target=Polymer.dom(optTriggeringEvent).rootTarget;if(domCon tainer.deepContains(target)){this._ripple.uiDownAction(optTriggeringEvent)}}}},g etRipple:function(){this.ensureRipple();return this._ripple},hasRipple:function( ){return Boolean(this._ripple)},_createRipple:function(){return document.createE lement("paper-ripple")},_noinkChanged:function(noink){if(this.hasRipple()){this. _ripple.noink=noink}}};Polymer.PaperInkyFocusBehaviorImpl={observers:["_focusedC hanged(receivedFocusFromKeyboard)"],_focusedChanged:function(receivedFocusFromKe yboard){if(receivedFocusFromKeyboard){this.ensureRipple()}if(this.hasRipple()){t his._ripple.holdDown=receivedFocusFromKeyboard}},_createRipple:function(){var ri pple=Polymer.PaperRippleBehavior._createRipple();ripple.id="ink";ripple.setAttri bute("center","");ripple.classList.add("circle");return ripple}};Polymer.PaperIn kyFocusBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperR ippleBehavior,Polymer.PaperInkyFocusBehaviorImpl];Polymer({is:"paper-icon-button ",hostAttributes:{role:"button",tabindex:"0"},behaviors:[Polymer.PaperInkyFocusB ehavior],properties:{src:{type:String},icon:{type:String},alt:{type:String,obser ver:"_altChanged"}},_altChanged:function(newValue,oldValue){var label=this.getAt tribute("aria-label");if(!label||oldValue==label){this.setAttribute("aria-label" ,newValue)}}});Polymer({is:"iron-iconset-svg",properties:{name:{type:String,obse rver:"_nameChanged"},size:{type:Number,value:24}},attached:function(){this.style .display="none"},getIconNames:function(){this._icons=this._createIconMap();retur n Object.keys(this._icons).map(function(n){return this.name+":"+n},this)},applyI con:function(element,iconName){element=element.root||element;this.removeIcon(ele ment);var svg=this._cloneIcon(iconName);if(svg){var pde=Polymer.dom(element);pde .insertBefore(svg,pde.childNodes[0]);return element._svgIcon=svg}return null},re moveIcon:function(element){if(element._svgIcon){Polymer.dom(element).removeChild (element._svgIcon);element._svgIcon=null}},_nameChanged:function(){new Polymer.I ronMeta({type:"iconset",key:this.name,value:this});this.async(function(){this.fi re("iron-iconset-added",this,{node:window})})},_createIconMap:function(){var ico ns=Object.create(null);Polymer.dom(this).querySelectorAll("[id]").forEach(functi on(icon){icons[icon.id]=icon});return icons},_cloneIcon:function(id){this._icons =this._icons||this._createIconMap();return this._prepareSvgClone(this._icons[id] ,this.size)},_prepareSvgClone:function(sourceSvg,size){if(sourceSvg){var content =sourceSvg.cloneNode(true),svg=document.createElementNS("http://www.w3.org/2000/ svg","svg"),viewBox=content.getAttribute("viewBox")||"0 0 "+size+" "+size;svg.se tAttribute("viewBox",viewBox);svg.setAttribute("preserveAspectRatio","xMidYMid m eet");svg.style.cssText="pointer-events: none; display: block; width: 100%; heig ht: 100%;";svg.appendChild(content).removeAttribute("id");return svg}return null }});
376 if (ident) throw Error('Invalid shortcut');
377 ident = part;
378 }
379 });
380 this.ident_ = ident;
381 this.mods_ = mods;
382 }
383 KeyboardShortcut.prototype = {
384 matchesEvent: function(e) {
385 if (e.key == this.ident_) {
386 var mods = this.mods_;
387 return [ 'altKey', 'ctrlKey', 'metaKey', 'shiftKey' ].every(function(k) {
388 return e[k] == !!mods[k];
389 });
390 }
391 return false;
392 }
393 };
394 var Command = cr.ui.define('command');
395 Command.prototype = {
396 __proto__: HTMLElement.prototype,
397 decorate: function() {
398 CommandManager.init(assert(this.ownerDocument));
399 if (this.hasAttribute('shortcut')) this.shortcut = this.getAttribute('shor tcut');
400 },
401 execute: function(opt_element) {
402 if (this.disabled) return;
403 var doc = this.ownerDocument;
404 if (doc.activeElement) {
405 var e = new Event('command', {
406 bubbles: true
407 });
408 e.command = this;
409 (opt_element || doc.activeElement).dispatchEvent(e);
410 }
411 },
412 canExecuteChange: function(opt_node) {
413 dispatchCanExecuteEvent(this, opt_node || this.ownerDocument.activeElement );
414 },
415 shortcut_: '',
416 get shortcut() {
417 return this.shortcut_;
418 },
419 set shortcut(shortcut) {
420 var oldShortcut = this.shortcut_;
421 if (shortcut !== oldShortcut) {
422 this.keyboardShortcuts_ = shortcut.split(/\s+/).map(function(shortcut) {
423 return new KeyboardShortcut(shortcut);
424 });
425 this.shortcut_ = shortcut;
426 cr.dispatchPropertyChange(this, 'shortcut', this.shortcut_, oldShortcut) ;
427 }
428 },
429 matchesEvent: function(e) {
430 if (!this.keyboardShortcuts_) return false;
431 return this.keyboardShortcuts_.some(function(keyboardShortcut) {
432 return keyboardShortcut.matchesEvent(e);
433 });
434 }
435 };
436 cr.defineProperty(Command, 'label', cr.PropertyKind.ATTR);
437 cr.defineProperty(Command, 'disabled', cr.PropertyKind.BOOL_ATTR);
438 cr.defineProperty(Command, 'hidden', cr.PropertyKind.BOOL_ATTR);
439 cr.defineProperty(Command, 'checked', cr.PropertyKind.BOOL_ATTR);
440 cr.defineProperty(Command, 'hideShortcutText', cr.PropertyKind.BOOL_ATTR);
441 function dispatchCanExecuteEvent(command, target) {
442 var e = new CanExecuteEvent(command);
443 target.dispatchEvent(e);
444 command.disabled = !e.canExecute;
445 }
446 var commandManagers = {};
447 function CommandManager(doc) {
448 doc.addEventListener('focus', this.handleFocus_.bind(this), true);
449 doc.addEventListener('keydown', this.handleKeyDown_.bind(this), false);
450 }
451 CommandManager.init = function(doc) {
452 var uid = cr.getUid(doc);
453 if (!(uid in commandManagers)) {
454 commandManagers[uid] = new CommandManager(doc);
455 }
456 };
457 CommandManager.prototype = {
458 handleFocus_: function(e) {
459 var target = e.target;
460 if (target.menu || target.command) return;
461 var commands = Array.prototype.slice.call(target.ownerDocument.querySelect orAll('command'));
462 commands.forEach(function(command) {
463 dispatchCanExecuteEvent(command, target);
464 });
465 },
466 handleKeyDown_: function(e) {
467 var target = e.target;
468 var commands = Array.prototype.slice.call(target.ownerDocument.querySelect orAll('command'));
469 for (var i = 0, command; command = commands[i]; i++) {
470 if (command.matchesEvent(e)) {
471 command.canExecuteChange();
472 if (!command.disabled) {
473 e.preventDefault();
474 e.stopPropagation();
475 command.execute();
476 return;
477 }
478 }
479 }
480 }
481 };
482 function CanExecuteEvent(command) {
483 var e = new Event('canExecute', {
484 bubbles: true,
485 cancelable: true
486 });
487 e.__proto__ = CanExecuteEvent.prototype;
488 e.command = command;
489 return e;
490 }
491 CanExecuteEvent.prototype = {
492 __proto__: Event.prototype,
493 command: null,
494 canExecute_: false,
495 get canExecute() {
496 return this.canExecute_;
497 },
498 set canExecute(canExecute) {
499 this.canExecute_ = !!canExecute;
500 this.stopPropagation();
501 this.preventDefault();
502 }
503 };
504 return {
505 Command: Command,
506 CanExecuteEvent: CanExecuteEvent
507 };
508 });
509
510 Polymer({
511 is: 'iron-media-query',
512 properties: {
513 queryMatches: {
514 type: Boolean,
515 value: false,
516 readOnly: true,
517 notify: true
518 },
519 query: {
520 type: String,
521 observer: 'queryChanged'
522 },
523 full: {
524 type: Boolean,
525 value: false
526 },
527 _boundMQHandler: {
528 value: function() {
529 return this.queryHandler.bind(this);
530 }
531 },
532 _mq: {
533 value: null
534 }
535 },
536 attached: function() {
537 this.style.display = 'none';
538 this.queryChanged();
539 },
540 detached: function() {
541 this._remove();
542 },
543 _add: function() {
544 if (this._mq) {
545 this._mq.addListener(this._boundMQHandler);
546 }
547 },
548 _remove: function() {
549 if (this._mq) {
550 this._mq.removeListener(this._boundMQHandler);
551 }
552 this._mq = null;
553 },
554 queryChanged: function() {
555 this._remove();
556 var query = this.query;
557 if (!query) {
558 return;
559 }
560 if (!this.full && query[0] !== '(') {
561 query = '(' + query + ')';
562 }
563 this._mq = window.matchMedia(query);
564 this._add();
565 this.queryHandler(this._mq);
566 },
567 queryHandler: function(mq) {
568 this._setQueryMatches(mq.matches);
569 }
570 });
571
572 Polymer.IronResizableBehavior = {
573 properties: {
574 _parentResizable: {
575 type: Object,
576 observer: '_parentResizableChanged'
577 },
578 _notifyingDescendant: {
579 type: Boolean,
580 value: false
581 }
582 },
583 listeners: {
584 'iron-request-resize-notifications': '_onIronRequestResizeNotifications'
585 },
586 created: function() {
587 this._interestedResizables = [];
588 this._boundNotifyResize = this.notifyResize.bind(this);
589 },
590 attached: function() {
591 this.fire('iron-request-resize-notifications', null, {
592 node: this,
593 bubbles: true,
594 cancelable: true
595 });
596 if (!this._parentResizable) {
597 window.addEventListener('resize', this._boundNotifyResize);
598 this.notifyResize();
599 }
600 },
601 detached: function() {
602 if (this._parentResizable) {
603 this._parentResizable.stopResizeNotificationsFor(this);
604 } else {
605 window.removeEventListener('resize', this._boundNotifyResize);
606 }
607 this._parentResizable = null;
608 },
609 notifyResize: function() {
610 if (!this.isAttached) {
611 return;
612 }
613 this._interestedResizables.forEach(function(resizable) {
614 if (this.resizerShouldNotify(resizable)) {
615 this._notifyDescendant(resizable);
616 }
617 }, this);
618 this._fireResize();
619 },
620 assignParentResizable: function(parentResizable) {
621 this._parentResizable = parentResizable;
622 },
623 stopResizeNotificationsFor: function(target) {
624 var index = this._interestedResizables.indexOf(target);
625 if (index > -1) {
626 this._interestedResizables.splice(index, 1);
627 this.unlisten(target, 'iron-resize', '_onDescendantIronResize');
628 }
629 },
630 resizerShouldNotify: function(element) {
631 return true;
632 },
633 _onDescendantIronResize: function(event) {
634 if (this._notifyingDescendant) {
635 event.stopPropagation();
636 return;
637 }
638 if (!Polymer.Settings.useShadow) {
639 this._fireResize();
640 }
641 },
642 _fireResize: function() {
643 this.fire('iron-resize', null, {
644 node: this,
645 bubbles: false
646 });
647 },
648 _onIronRequestResizeNotifications: function(event) {
649 var target = event.path ? event.path[0] : event.target;
650 if (target === this) {
651 return;
652 }
653 if (this._interestedResizables.indexOf(target) === -1) {
654 this._interestedResizables.push(target);
655 this.listen(target, 'iron-resize', '_onDescendantIronResize');
656 }
657 target.assignParentResizable(this);
658 this._notifyDescendant(target);
659 event.stopPropagation();
660 },
661 _parentResizableChanged: function(parentResizable) {
662 if (parentResizable) {
663 window.removeEventListener('resize', this._boundNotifyResize);
664 }
665 },
666 _notifyDescendant: function(descendant) {
667 if (!this.isAttached) {
668 return;
669 }
670 this._notifyingDescendant = true;
671 descendant.notifyResize();
672 this._notifyingDescendant = false;
673 }
674 };
675
676 Polymer.IronSelection = function(selectCallback) {
677 this.selection = [];
678 this.selectCallback = selectCallback;
679 };
680
681 Polymer.IronSelection.prototype = {
682 get: function() {
683 return this.multi ? this.selection.slice() : this.selection[0];
684 },
685 clear: function(excludes) {
686 this.selection.slice().forEach(function(item) {
687 if (!excludes || excludes.indexOf(item) < 0) {
688 this.setItemSelected(item, false);
689 }
690 }, this);
691 },
692 isSelected: function(item) {
693 return this.selection.indexOf(item) >= 0;
694 },
695 setItemSelected: function(item, isSelected) {
696 if (item != null) {
697 if (isSelected !== this.isSelected(item)) {
698 if (isSelected) {
699 this.selection.push(item);
700 } else {
701 var i = this.selection.indexOf(item);
702 if (i >= 0) {
703 this.selection.splice(i, 1);
704 }
705 }
706 if (this.selectCallback) {
707 this.selectCallback(item, isSelected);
708 }
709 }
710 }
711 },
712 select: function(item) {
713 if (this.multi) {
714 this.toggle(item);
715 } else if (this.get() !== item) {
716 this.setItemSelected(this.get(), false);
717 this.setItemSelected(item, true);
718 }
719 },
720 toggle: function(item) {
721 this.setItemSelected(item, !this.isSelected(item));
722 }
723 };
724
725 Polymer.IronSelectableBehavior = {
726 properties: {
727 attrForSelected: {
728 type: String,
729 value: null
730 },
731 selected: {
732 type: String,
733 notify: true
734 },
735 selectedItem: {
736 type: Object,
737 readOnly: true,
738 notify: true
739 },
740 activateEvent: {
741 type: String,
742 value: 'tap',
743 observer: '_activateEventChanged'
744 },
745 selectable: String,
746 selectedClass: {
747 type: String,
748 value: 'iron-selected'
749 },
750 selectedAttribute: {
751 type: String,
752 value: null
753 },
754 fallbackSelection: {
755 type: String,
756 value: null
757 },
758 items: {
759 type: Array,
760 readOnly: true,
761 notify: true,
762 value: function() {
763 return [];
764 }
765 },
766 _excludedLocalNames: {
767 type: Object,
768 value: function() {
769 return {
770 template: 1
771 };
772 }
773 }
774 },
775 observers: [ '_updateAttrForSelected(attrForSelected)', '_updateSelected(selec ted)', '_checkFallback(fallbackSelection)' ],
776 created: function() {
777 this._bindFilterItem = this._filterItem.bind(this);
778 this._selection = new Polymer.IronSelection(this._applySelection.bind(this)) ;
779 },
780 attached: function() {
781 this._observer = this._observeItems(this);
782 this._updateItems();
783 if (!this._shouldUpdateSelection) {
784 this._updateSelected();
785 }
786 this._addListener(this.activateEvent);
787 },
788 detached: function() {
789 if (this._observer) {
790 Polymer.dom(this).unobserveNodes(this._observer);
791 }
792 this._removeListener(this.activateEvent);
793 },
794 indexOf: function(item) {
795 return this.items.indexOf(item);
796 },
797 select: function(value) {
798 this.selected = value;
799 },
800 selectPrevious: function() {
801 var length = this.items.length;
802 var index = (Number(this._valueToIndex(this.selected)) - 1 + length) % lengt h;
803 this.selected = this._indexToValue(index);
804 },
805 selectNext: function() {
806 var index = (Number(this._valueToIndex(this.selected)) + 1) % this.items.len gth;
807 this.selected = this._indexToValue(index);
808 },
809 selectIndex: function(index) {
810 this.select(this._indexToValue(index));
811 },
812 forceSynchronousItemUpdate: function() {
813 this._updateItems();
814 },
815 get _shouldUpdateSelection() {
816 return this.selected != null;
817 },
818 _checkFallback: function() {
819 if (this._shouldUpdateSelection) {
820 this._updateSelected();
821 }
822 },
823 _addListener: function(eventName) {
824 this.listen(this, eventName, '_activateHandler');
825 },
826 _removeListener: function(eventName) {
827 this.unlisten(this, eventName, '_activateHandler');
828 },
829 _activateEventChanged: function(eventName, old) {
830 this._removeListener(old);
831 this._addListener(eventName);
832 },
833 _updateItems: function() {
834 var nodes = Polymer.dom(this).queryDistributedElements(this.selectable || '* ');
835 nodes = Array.prototype.filter.call(nodes, this._bindFilterItem);
836 this._setItems(nodes);
837 },
838 _updateAttrForSelected: function() {
839 if (this._shouldUpdateSelection) {
840 this.selected = this._indexToValue(this.indexOf(this.selectedItem));
841 }
842 },
843 _updateSelected: function() {
844 this._selectSelected(this.selected);
845 },
846 _selectSelected: function(selected) {
847 this._selection.select(this._valueToItem(this.selected));
848 if (this.fallbackSelection && this.items.length && this._selection.get() === undefined) {
849 this.selected = this.fallbackSelection;
850 }
851 },
852 _filterItem: function(node) {
853 return !this._excludedLocalNames[node.localName];
854 },
855 _valueToItem: function(value) {
856 return value == null ? null : this.items[this._valueToIndex(value)];
857 },
858 _valueToIndex: function(value) {
859 if (this.attrForSelected) {
860 for (var i = 0, item; item = this.items[i]; i++) {
861 if (this._valueForItem(item) == value) {
862 return i;
863 }
864 }
865 } else {
866 return Number(value);
867 }
868 },
869 _indexToValue: function(index) {
870 if (this.attrForSelected) {
871 var item = this.items[index];
872 if (item) {
873 return this._valueForItem(item);
874 }
875 } else {
876 return index;
877 }
878 },
879 _valueForItem: function(item) {
880 var propValue = item[Polymer.CaseMap.dashToCamelCase(this.attrForSelected)];
881 return propValue != undefined ? propValue : item.getAttribute(this.attrForSe lected);
882 },
883 _applySelection: function(item, isSelected) {
884 if (this.selectedClass) {
885 this.toggleClass(this.selectedClass, isSelected, item);
886 }
887 if (this.selectedAttribute) {
888 this.toggleAttribute(this.selectedAttribute, isSelected, item);
889 }
890 this._selectionChange();
891 this.fire('iron-' + (isSelected ? 'select' : 'deselect'), {
892 item: item
893 });
894 },
895 _selectionChange: function() {
896 this._setSelectedItem(this._selection.get());
897 },
898 _observeItems: function(node) {
899 return Polymer.dom(node).observeNodes(function(mutation) {
900 this._updateItems();
901 if (this._shouldUpdateSelection) {
902 this._updateSelected();
903 }
904 this.fire('iron-items-changed', mutation, {
905 bubbles: false,
906 cancelable: false
907 });
908 });
909 },
910 _activateHandler: function(e) {
911 var t = e.target;
912 var items = this.items;
913 while (t && t != this) {
914 var i = items.indexOf(t);
915 if (i >= 0) {
916 var value = this._indexToValue(i);
917 this._itemActivate(value, t);
918 return;
919 }
920 t = t.parentNode;
921 }
922 },
923 _itemActivate: function(value, item) {
924 if (!this.fire('iron-activate', {
925 selected: value,
926 item: item
927 }, {
928 cancelable: true
929 }).defaultPrevented) {
930 this.select(value);
931 }
932 }
933 };
934
935 Polymer({
936 is: 'iron-pages',
937 behaviors: [ Polymer.IronResizableBehavior, Polymer.IronSelectableBehavior ],
938 properties: {
939 activateEvent: {
940 type: String,
941 value: null
942 }
943 },
944 observers: [ '_selectedPageChanged(selected)' ],
945 _selectedPageChanged: function(selected, old) {
946 this.async(this.notifyResize);
947 }
948 });
949
950 Polymer.IronScrollTargetBehavior = {
951 properties: {
952 scrollTarget: {
953 type: HTMLElement,
954 value: function() {
955 return this._defaultScrollTarget;
956 }
957 }
958 },
959 observers: [ '_scrollTargetChanged(scrollTarget, isAttached)' ],
960 _scrollTargetChanged: function(scrollTarget, isAttached) {
961 var eventTarget;
962 if (this._oldScrollTarget) {
963 eventTarget = this._oldScrollTarget === this._doc ? window : this._oldScro llTarget;
964 eventTarget.removeEventListener('scroll', this._boundScrollHandler);
965 this._oldScrollTarget = null;
966 }
967 if (!isAttached) {
968 return;
969 }
970 if (scrollTarget === 'document') {
971 this.scrollTarget = this._doc;
972 } else if (typeof scrollTarget === 'string') {
973 this.scrollTarget = this.domHost ? this.domHost.$[scrollTarget] : Polymer. dom(this.ownerDocument).querySelector('#' + scrollTarget);
974 } else if (this._isValidScrollTarget()) {
975 eventTarget = scrollTarget === this._doc ? window : scrollTarget;
976 this._boundScrollHandler = this._boundScrollHandler || this._scrollHandler .bind(this);
977 this._oldScrollTarget = scrollTarget;
978 eventTarget.addEventListener('scroll', this._boundScrollHandler);
979 }
980 },
981 _scrollHandler: function scrollHandler() {},
982 get _defaultScrollTarget() {
983 return this._doc;
984 },
985 get _doc() {
986 return this.ownerDocument.documentElement;
987 },
988 get _scrollTop() {
989 if (this._isValidScrollTarget()) {
990 return this.scrollTarget === this._doc ? window.pageYOffset : this.scrollT arget.scrollTop;
991 }
992 return 0;
993 },
994 get _scrollLeft() {
995 if (this._isValidScrollTarget()) {
996 return this.scrollTarget === this._doc ? window.pageXOffset : this.scrollT arget.scrollLeft;
997 }
998 return 0;
999 },
1000 set _scrollTop(top) {
1001 if (this.scrollTarget === this._doc) {
1002 window.scrollTo(window.pageXOffset, top);
1003 } else if (this._isValidScrollTarget()) {
1004 this.scrollTarget.scrollTop = top;
1005 }
1006 },
1007 set _scrollLeft(left) {
1008 if (this.scrollTarget === this._doc) {
1009 window.scrollTo(left, window.pageYOffset);
1010 } else if (this._isValidScrollTarget()) {
1011 this.scrollTarget.scrollLeft = left;
1012 }
1013 },
1014 scroll: function(left, top) {
1015 if (this.scrollTarget === this._doc) {
1016 window.scrollTo(left, top);
1017 } else if (this._isValidScrollTarget()) {
1018 this.scrollTarget.scrollLeft = left;
1019 this.scrollTarget.scrollTop = top;
1020 }
1021 },
1022 get _scrollTargetWidth() {
1023 if (this._isValidScrollTarget()) {
1024 return this.scrollTarget === this._doc ? window.innerWidth : this.scrollTa rget.offsetWidth;
1025 }
1026 return 0;
1027 },
1028 get _scrollTargetHeight() {
1029 if (this._isValidScrollTarget()) {
1030 return this.scrollTarget === this._doc ? window.innerHeight : this.scrollT arget.offsetHeight;
1031 }
1032 return 0;
1033 },
1034 _isValidScrollTarget: function() {
1035 return this.scrollTarget instanceof HTMLElement;
1036 }
1037 };
1038
1039 (function() {
1040 var metaDatas = {};
1041 var metaArrays = {};
1042 var singleton = null;
1043 Polymer.IronMeta = Polymer({
1044 is: 'iron-meta',
1045 properties: {
1046 type: {
1047 type: String,
1048 value: 'default',
1049 observer: '_typeChanged'
1050 },
1051 key: {
1052 type: String,
1053 observer: '_keyChanged'
1054 },
1055 value: {
1056 type: Object,
1057 notify: true,
1058 observer: '_valueChanged'
1059 },
1060 self: {
1061 type: Boolean,
1062 observer: '_selfChanged'
1063 },
1064 list: {
1065 type: Array,
1066 notify: true
1067 }
1068 },
1069 hostAttributes: {
1070 hidden: true
1071 },
1072 factoryImpl: function(config) {
1073 if (config) {
1074 for (var n in config) {
1075 switch (n) {
1076 case 'type':
1077 case 'key':
1078 case 'value':
1079 this[n] = config[n];
1080 break;
1081 }
1082 }
1083 }
1084 },
1085 created: function() {
1086 this._metaDatas = metaDatas;
1087 this._metaArrays = metaArrays;
1088 },
1089 _keyChanged: function(key, old) {
1090 this._resetRegistration(old);
1091 },
1092 _valueChanged: function(value) {
1093 this._resetRegistration(this.key);
1094 },
1095 _selfChanged: function(self) {
1096 if (self) {
1097 this.value = this;
1098 }
1099 },
1100 _typeChanged: function(type) {
1101 this._unregisterKey(this.key);
1102 if (!metaDatas[type]) {
1103 metaDatas[type] = {};
1104 }
1105 this._metaData = metaDatas[type];
1106 if (!metaArrays[type]) {
1107 metaArrays[type] = [];
1108 }
1109 this.list = metaArrays[type];
1110 this._registerKeyValue(this.key, this.value);
1111 },
1112 byKey: function(key) {
1113 return this._metaData && this._metaData[key];
1114 },
1115 _resetRegistration: function(oldKey) {
1116 this._unregisterKey(oldKey);
1117 this._registerKeyValue(this.key, this.value);
1118 },
1119 _unregisterKey: function(key) {
1120 this._unregister(key, this._metaData, this.list);
1121 },
1122 _registerKeyValue: function(key, value) {
1123 this._register(key, value, this._metaData, this.list);
1124 },
1125 _register: function(key, value, data, list) {
1126 if (key && data && value !== undefined) {
1127 data[key] = value;
1128 list.push(value);
1129 }
1130 },
1131 _unregister: function(key, data, list) {
1132 if (key && data) {
1133 if (key in data) {
1134 var value = data[key];
1135 delete data[key];
1136 this.arrayDelete(list, value);
1137 }
1138 }
1139 }
1140 });
1141 Polymer.IronMeta.getIronMeta = function getIronMeta() {
1142 if (singleton === null) {
1143 singleton = new Polymer.IronMeta();
1144 }
1145 return singleton;
1146 };
1147 Polymer.IronMetaQuery = Polymer({
1148 is: 'iron-meta-query',
1149 properties: {
1150 type: {
1151 type: String,
1152 value: 'default',
1153 observer: '_typeChanged'
1154 },
1155 key: {
1156 type: String,
1157 observer: '_keyChanged'
1158 },
1159 value: {
1160 type: Object,
1161 notify: true,
1162 readOnly: true
1163 },
1164 list: {
1165 type: Array,
1166 notify: true
1167 }
1168 },
1169 factoryImpl: function(config) {
1170 if (config) {
1171 for (var n in config) {
1172 switch (n) {
1173 case 'type':
1174 case 'key':
1175 this[n] = config[n];
1176 break;
1177 }
1178 }
1179 }
1180 },
1181 created: function() {
1182 this._metaDatas = metaDatas;
1183 this._metaArrays = metaArrays;
1184 },
1185 _keyChanged: function(key) {
1186 this._setValue(this._metaData && this._metaData[key]);
1187 },
1188 _typeChanged: function(type) {
1189 this._metaData = metaDatas[type];
1190 this.list = metaArrays[type];
1191 if (this.key) {
1192 this._keyChanged(this.key);
1193 }
1194 },
1195 byKey: function(key) {
1196 return this._metaData && this._metaData[key];
1197 }
1198 });
1199 })();
1200
1201 Polymer({
1202 is: 'iron-icon',
1203 properties: {
1204 icon: {
1205 type: String,
1206 observer: '_iconChanged'
1207 },
1208 theme: {
1209 type: String,
1210 observer: '_updateIcon'
1211 },
1212 src: {
1213 type: String,
1214 observer: '_srcChanged'
1215 },
1216 _meta: {
1217 value: Polymer.Base.create('iron-meta', {
1218 type: 'iconset'
1219 }),
1220 observer: '_updateIcon'
1221 }
1222 },
1223 _DEFAULT_ICONSET: 'icons',
1224 _iconChanged: function(icon) {
1225 var parts = (icon || '').split(':');
1226 this._iconName = parts.pop();
1227 this._iconsetName = parts.pop() || this._DEFAULT_ICONSET;
1228 this._updateIcon();
1229 },
1230 _srcChanged: function(src) {
1231 this._updateIcon();
1232 },
1233 _usesIconset: function() {
1234 return this.icon || !this.src;
1235 },
1236 _updateIcon: function() {
1237 if (this._usesIconset()) {
1238 if (this._img && this._img.parentNode) {
1239 Polymer.dom(this.root).removeChild(this._img);
1240 }
1241 if (this._iconName === "") {
1242 if (this._iconset) {
1243 this._iconset.removeIcon(this);
1244 }
1245 } else if (this._iconsetName && this._meta) {
1246 this._iconset = this._meta.byKey(this._iconsetName);
1247 if (this._iconset) {
1248 this._iconset.applyIcon(this, this._iconName, this.theme);
1249 this.unlisten(window, 'iron-iconset-added', '_updateIcon');
1250 } else {
1251 this.listen(window, 'iron-iconset-added', '_updateIcon');
1252 }
1253 }
1254 } else {
1255 if (this._iconset) {
1256 this._iconset.removeIcon(this);
1257 }
1258 if (!this._img) {
1259 this._img = document.createElement('img');
1260 this._img.style.width = '100%';
1261 this._img.style.height = '100%';
1262 this._img.draggable = false;
1263 }
1264 this._img.src = this.src;
1265 Polymer.dom(this.root).appendChild(this._img);
1266 }
1267 }
1268 });
1269
1270 (function() {
1271 'use strict';
1272 var KEY_IDENTIFIER = {
1273 'U+0008': 'backspace',
1274 'U+0009': 'tab',
1275 'U+001B': 'esc',
1276 'U+0020': 'space',
1277 'U+007F': 'del'
1278 };
1279 var KEY_CODE = {
1280 8: 'backspace',
1281 9: 'tab',
1282 13: 'enter',
1283 27: 'esc',
1284 33: 'pageup',
1285 34: 'pagedown',
1286 35: 'end',
1287 36: 'home',
1288 32: 'space',
1289 37: 'left',
1290 38: 'up',
1291 39: 'right',
1292 40: 'down',
1293 46: 'del',
1294 106: '*'
1295 };
1296 var MODIFIER_KEYS = {
1297 shift: 'shiftKey',
1298 ctrl: 'ctrlKey',
1299 alt: 'altKey',
1300 meta: 'metaKey'
1301 };
1302 var KEY_CHAR = /[a-z0-9*]/;
1303 var IDENT_CHAR = /U\+/;
1304 var ARROW_KEY = /^arrow/;
1305 var SPACE_KEY = /^space(bar)?/;
1306 var ESC_KEY = /^escape$/;
1307 function transformKey(key, noSpecialChars) {
1308 var validKey = '';
1309 if (key) {
1310 var lKey = key.toLowerCase();
1311 if (lKey === ' ' || SPACE_KEY.test(lKey)) {
1312 validKey = 'space';
1313 } else if (ESC_KEY.test(lKey)) {
1314 validKey = 'esc';
1315 } else if (lKey.length == 1) {
1316 if (!noSpecialChars || KEY_CHAR.test(lKey)) {
1317 validKey = lKey;
1318 }
1319 } else if (ARROW_KEY.test(lKey)) {
1320 validKey = lKey.replace('arrow', '');
1321 } else if (lKey == 'multiply') {
1322 validKey = '*';
1323 } else {
1324 validKey = lKey;
1325 }
1326 }
1327 return validKey;
1328 }
1329 function transformKeyIdentifier(keyIdent) {
1330 var validKey = '';
1331 if (keyIdent) {
1332 if (keyIdent in KEY_IDENTIFIER) {
1333 validKey = KEY_IDENTIFIER[keyIdent];
1334 } else if (IDENT_CHAR.test(keyIdent)) {
1335 keyIdent = parseInt(keyIdent.replace('U+', '0x'), 16);
1336 validKey = String.fromCharCode(keyIdent).toLowerCase();
1337 } else {
1338 validKey = keyIdent.toLowerCase();
1339 }
1340 }
1341 return validKey;
1342 }
1343 function transformKeyCode(keyCode) {
1344 var validKey = '';
1345 if (Number(keyCode)) {
1346 if (keyCode >= 65 && keyCode <= 90) {
1347 validKey = String.fromCharCode(32 + keyCode);
1348 } else if (keyCode >= 112 && keyCode <= 123) {
1349 validKey = 'f' + (keyCode - 112);
1350 } else if (keyCode >= 48 && keyCode <= 57) {
1351 validKey = String(keyCode - 48);
1352 } else if (keyCode >= 96 && keyCode <= 105) {
1353 validKey = String(keyCode - 96);
1354 } else {
1355 validKey = KEY_CODE[keyCode];
1356 }
1357 }
1358 return validKey;
1359 }
1360 function normalizedKeyForEvent(keyEvent, noSpecialChars) {
1361 if (keyEvent.key) {
1362 return transformKey(keyEvent.key, noSpecialChars);
1363 }
1364 if (keyEvent.detail && keyEvent.detail.key) {
1365 return transformKey(keyEvent.detail.key, noSpecialChars);
1366 }
1367 return transformKeyIdentifier(keyEvent.keyIdentifier) || transformKeyCode(ke yEvent.keyCode) || '';
1368 }
1369 function keyComboMatchesEvent(keyCombo, event) {
1370 var keyEvent = normalizedKeyForEvent(event, keyCombo.hasModifiers);
1371 return keyEvent === keyCombo.key && (!keyCombo.hasModifiers || !!event.shift Key === !!keyCombo.shiftKey && !!event.ctrlKey === !!keyCombo.ctrlKey && !!event .altKey === !!keyCombo.altKey && !!event.metaKey === !!keyCombo.metaKey);
1372 }
1373 function parseKeyComboString(keyComboString) {
1374 if (keyComboString.length === 1) {
1375 return {
1376 combo: keyComboString,
1377 key: keyComboString,
1378 event: 'keydown'
1379 };
1380 }
1381 return keyComboString.split('+').reduce(function(parsedKeyCombo, keyComboPar t) {
1382 var eventParts = keyComboPart.split(':');
1383 var keyName = eventParts[0];
1384 var event = eventParts[1];
1385 if (keyName in MODIFIER_KEYS) {
1386 parsedKeyCombo[MODIFIER_KEYS[keyName]] = true;
1387 parsedKeyCombo.hasModifiers = true;
1388 } else {
1389 parsedKeyCombo.key = keyName;
1390 parsedKeyCombo.event = event || 'keydown';
1391 }
1392 return parsedKeyCombo;
1393 }, {
1394 combo: keyComboString.split(':').shift()
1395 });
1396 }
1397 function parseEventString(eventString) {
1398 return eventString.trim().split(' ').map(function(keyComboString) {
1399 return parseKeyComboString(keyComboString);
1400 });
1401 }
1402 Polymer.IronA11yKeysBehavior = {
1403 properties: {
1404 keyEventTarget: {
1405 type: Object,
1406 value: function() {
1407 return this;
1408 }
1409 },
1410 stopKeyboardEventPropagation: {
1411 type: Boolean,
1412 value: false
1413 },
1414 _boundKeyHandlers: {
1415 type: Array,
1416 value: function() {
1417 return [];
1418 }
1419 },
1420 _imperativeKeyBindings: {
1421 type: Object,
1422 value: function() {
1423 return {};
1424 }
1425 }
1426 },
1427 observers: [ '_resetKeyEventListeners(keyEventTarget, _boundKeyHandlers)' ],
1428 keyBindings: {},
1429 registered: function() {
1430 this._prepKeyBindings();
1431 },
1432 attached: function() {
1433 this._listenKeyEventListeners();
1434 },
1435 detached: function() {
1436 this._unlistenKeyEventListeners();
1437 },
1438 addOwnKeyBinding: function(eventString, handlerName) {
1439 this._imperativeKeyBindings[eventString] = handlerName;
1440 this._prepKeyBindings();
1441 this._resetKeyEventListeners();
1442 },
1443 removeOwnKeyBindings: function() {
1444 this._imperativeKeyBindings = {};
1445 this._prepKeyBindings();
1446 this._resetKeyEventListeners();
1447 },
1448 keyboardEventMatchesKeys: function(event, eventString) {
1449 var keyCombos = parseEventString(eventString);
1450 for (var i = 0; i < keyCombos.length; ++i) {
1451 if (keyComboMatchesEvent(keyCombos[i], event)) {
1452 return true;
1453 }
1454 }
1455 return false;
1456 },
1457 _collectKeyBindings: function() {
1458 var keyBindings = this.behaviors.map(function(behavior) {
1459 return behavior.keyBindings;
1460 });
1461 if (keyBindings.indexOf(this.keyBindings) === -1) {
1462 keyBindings.push(this.keyBindings);
1463 }
1464 return keyBindings;
1465 },
1466 _prepKeyBindings: function() {
1467 this._keyBindings = {};
1468 this._collectKeyBindings().forEach(function(keyBindings) {
1469 for (var eventString in keyBindings) {
1470 this._addKeyBinding(eventString, keyBindings[eventString]);
1471 }
1472 }, this);
1473 for (var eventString in this._imperativeKeyBindings) {
1474 this._addKeyBinding(eventString, this._imperativeKeyBindings[eventString ]);
1475 }
1476 for (var eventName in this._keyBindings) {
1477 this._keyBindings[eventName].sort(function(kb1, kb2) {
1478 var b1 = kb1[0].hasModifiers;
1479 var b2 = kb2[0].hasModifiers;
1480 return b1 === b2 ? 0 : b1 ? -1 : 1;
1481 });
1482 }
1483 },
1484 _addKeyBinding: function(eventString, handlerName) {
1485 parseEventString(eventString).forEach(function(keyCombo) {
1486 this._keyBindings[keyCombo.event] = this._keyBindings[keyCombo.event] || [];
1487 this._keyBindings[keyCombo.event].push([ keyCombo, handlerName ]);
1488 }, this);
1489 },
1490 _resetKeyEventListeners: function() {
1491 this._unlistenKeyEventListeners();
1492 if (this.isAttached) {
1493 this._listenKeyEventListeners();
1494 }
1495 },
1496 _listenKeyEventListeners: function() {
1497 if (!this.keyEventTarget) {
1498 return;
1499 }
1500 Object.keys(this._keyBindings).forEach(function(eventName) {
1501 var keyBindings = this._keyBindings[eventName];
1502 var boundKeyHandler = this._onKeyBindingEvent.bind(this, keyBindings);
1503 this._boundKeyHandlers.push([ this.keyEventTarget, eventName, boundKeyHa ndler ]);
1504 this.keyEventTarget.addEventListener(eventName, boundKeyHandler);
1505 }, this);
1506 },
1507 _unlistenKeyEventListeners: function() {
1508 var keyHandlerTuple;
1509 var keyEventTarget;
1510 var eventName;
1511 var boundKeyHandler;
1512 while (this._boundKeyHandlers.length) {
1513 keyHandlerTuple = this._boundKeyHandlers.pop();
1514 keyEventTarget = keyHandlerTuple[0];
1515 eventName = keyHandlerTuple[1];
1516 boundKeyHandler = keyHandlerTuple[2];
1517 keyEventTarget.removeEventListener(eventName, boundKeyHandler);
1518 }
1519 },
1520 _onKeyBindingEvent: function(keyBindings, event) {
1521 if (this.stopKeyboardEventPropagation) {
1522 event.stopPropagation();
1523 }
1524 if (event.defaultPrevented) {
1525 return;
1526 }
1527 for (var i = 0; i < keyBindings.length; i++) {
1528 var keyCombo = keyBindings[i][0];
1529 var handlerName = keyBindings[i][1];
1530 if (keyComboMatchesEvent(keyCombo, event)) {
1531 this._triggerKeyHandler(keyCombo, handlerName, event);
1532 if (event.defaultPrevented) {
1533 return;
1534 }
1535 }
1536 }
1537 },
1538 _triggerKeyHandler: function(keyCombo, handlerName, keyboardEvent) {
1539 var detail = Object.create(keyCombo);
1540 detail.keyboardEvent = keyboardEvent;
1541 var event = new CustomEvent(keyCombo.event, {
1542 detail: detail,
1543 cancelable: true
1544 });
1545 this[handlerName].call(this, event);
1546 if (event.defaultPrevented) {
1547 keyboardEvent.preventDefault();
1548 }
1549 }
1550 };
1551 })();
1552
1553 Polymer.IronControlState = {
1554 properties: {
1555 focused: {
1556 type: Boolean,
1557 value: false,
1558 notify: true,
1559 readOnly: true,
1560 reflectToAttribute: true
1561 },
1562 disabled: {
1563 type: Boolean,
1564 value: false,
1565 notify: true,
1566 observer: '_disabledChanged',
1567 reflectToAttribute: true
1568 },
1569 _oldTabIndex: {
1570 type: Number
1571 },
1572 _boundFocusBlurHandler: {
1573 type: Function,
1574 value: function() {
1575 return this._focusBlurHandler.bind(this);
1576 }
1577 }
1578 },
1579 observers: [ '_changedControlState(focused, disabled)' ],
1580 ready: function() {
1581 this.addEventListener('focus', this._boundFocusBlurHandler, true);
1582 this.addEventListener('blur', this._boundFocusBlurHandler, true);
1583 },
1584 _focusBlurHandler: function(event) {
1585 if (event.target === this) {
1586 this._setFocused(event.type === 'focus');
1587 } else if (!this.shadowRoot) {
1588 var target = Polymer.dom(event).localTarget;
1589 if (!this.isLightDescendant(target)) {
1590 this.fire(event.type, {
1591 sourceEvent: event
1592 }, {
1593 node: this,
1594 bubbles: event.bubbles,
1595 cancelable: event.cancelable
1596 });
1597 }
1598 }
1599 },
1600 _disabledChanged: function(disabled, old) {
1601 this.setAttribute('aria-disabled', disabled ? 'true' : 'false');
1602 this.style.pointerEvents = disabled ? 'none' : '';
1603 if (disabled) {
1604 this._oldTabIndex = this.tabIndex;
1605 this._setFocused(false);
1606 this.tabIndex = -1;
1607 this.blur();
1608 } else if (this._oldTabIndex !== undefined) {
1609 this.tabIndex = this._oldTabIndex;
1610 }
1611 },
1612 _changedControlState: function() {
1613 if (this._controlStateChanged) {
1614 this._controlStateChanged();
1615 }
1616 }
1617 };
1618
1619 Polymer.IronButtonStateImpl = {
1620 properties: {
1621 pressed: {
1622 type: Boolean,
1623 readOnly: true,
1624 value: false,
1625 reflectToAttribute: true,
1626 observer: '_pressedChanged'
1627 },
1628 toggles: {
1629 type: Boolean,
1630 value: false,
1631 reflectToAttribute: true
1632 },
1633 active: {
1634 type: Boolean,
1635 value: false,
1636 notify: true,
1637 reflectToAttribute: true
1638 },
1639 pointerDown: {
1640 type: Boolean,
1641 readOnly: true,
1642 value: false
1643 },
1644 receivedFocusFromKeyboard: {
1645 type: Boolean,
1646 readOnly: true
1647 },
1648 ariaActiveAttribute: {
1649 type: String,
1650 value: 'aria-pressed',
1651 observer: '_ariaActiveAttributeChanged'
1652 }
1653 },
1654 listeners: {
1655 down: '_downHandler',
1656 up: '_upHandler',
1657 tap: '_tapHandler'
1658 },
1659 observers: [ '_detectKeyboardFocus(focused)', '_activeChanged(active, ariaActi veAttribute)' ],
1660 keyBindings: {
1661 'enter:keydown': '_asyncClick',
1662 'space:keydown': '_spaceKeyDownHandler',
1663 'space:keyup': '_spaceKeyUpHandler'
1664 },
1665 _mouseEventRe: /^mouse/,
1666 _tapHandler: function() {
1667 if (this.toggles) {
1668 this._userActivate(!this.active);
1669 } else {
1670 this.active = false;
1671 }
1672 },
1673 _detectKeyboardFocus: function(focused) {
1674 this._setReceivedFocusFromKeyboard(!this.pointerDown && focused);
1675 },
1676 _userActivate: function(active) {
1677 if (this.active !== active) {
1678 this.active = active;
1679 this.fire('change');
1680 }
1681 },
1682 _downHandler: function(event) {
1683 this._setPointerDown(true);
1684 this._setPressed(true);
1685 this._setReceivedFocusFromKeyboard(false);
1686 },
1687 _upHandler: function() {
1688 this._setPointerDown(false);
1689 this._setPressed(false);
1690 },
1691 _spaceKeyDownHandler: function(event) {
1692 var keyboardEvent = event.detail.keyboardEvent;
1693 var target = Polymer.dom(keyboardEvent).localTarget;
1694 if (this.isLightDescendant(target)) return;
1695 keyboardEvent.preventDefault();
1696 keyboardEvent.stopImmediatePropagation();
1697 this._setPressed(true);
1698 },
1699 _spaceKeyUpHandler: function(event) {
1700 var keyboardEvent = event.detail.keyboardEvent;
1701 var target = Polymer.dom(keyboardEvent).localTarget;
1702 if (this.isLightDescendant(target)) return;
1703 if (this.pressed) {
1704 this._asyncClick();
1705 }
1706 this._setPressed(false);
1707 },
1708 _asyncClick: function() {
1709 this.async(function() {
1710 this.click();
1711 }, 1);
1712 },
1713 _pressedChanged: function(pressed) {
1714 this._changedButtonState();
1715 },
1716 _ariaActiveAttributeChanged: function(value, oldValue) {
1717 if (oldValue && oldValue != value && this.hasAttribute(oldValue)) {
1718 this.removeAttribute(oldValue);
1719 }
1720 },
1721 _activeChanged: function(active, ariaActiveAttribute) {
1722 if (this.toggles) {
1723 this.setAttribute(this.ariaActiveAttribute, active ? 'true' : 'false');
1724 } else {
1725 this.removeAttribute(this.ariaActiveAttribute);
1726 }
1727 this._changedButtonState();
1728 },
1729 _controlStateChanged: function() {
1730 if (this.disabled) {
1731 this._setPressed(false);
1732 } else {
1733 this._changedButtonState();
1734 }
1735 },
1736 _changedButtonState: function() {
1737 if (this._buttonStateChanged) {
1738 this._buttonStateChanged();
1739 }
1740 }
1741 };
1742
1743 Polymer.IronButtonState = [ Polymer.IronA11yKeysBehavior, Polymer.IronButtonStat eImpl ];
1744
1745 (function() {
1746 var Utility = {
1747 distance: function(x1, y1, x2, y2) {
1748 var xDelta = x1 - x2;
1749 var yDelta = y1 - y2;
1750 return Math.sqrt(xDelta * xDelta + yDelta * yDelta);
1751 },
1752 now: window.performance && window.performance.now ? window.performance.now.b ind(window.performance) : Date.now
1753 };
1754 function ElementMetrics(element) {
1755 this.element = element;
1756 this.width = this.boundingRect.width;
1757 this.height = this.boundingRect.height;
1758 this.size = Math.max(this.width, this.height);
1759 }
1760 ElementMetrics.prototype = {
1761 get boundingRect() {
1762 return this.element.getBoundingClientRect();
1763 },
1764 furthestCornerDistanceFrom: function(x, y) {
1765 var topLeft = Utility.distance(x, y, 0, 0);
1766 var topRight = Utility.distance(x, y, this.width, 0);
1767 var bottomLeft = Utility.distance(x, y, 0, this.height);
1768 var bottomRight = Utility.distance(x, y, this.width, this.height);
1769 return Math.max(topLeft, topRight, bottomLeft, bottomRight);
1770 }
1771 };
1772 function Ripple(element) {
1773 this.element = element;
1774 this.color = window.getComputedStyle(element).color;
1775 this.wave = document.createElement('div');
1776 this.waveContainer = document.createElement('div');
1777 this.wave.style.backgroundColor = this.color;
1778 this.wave.classList.add('wave');
1779 this.waveContainer.classList.add('wave-container');
1780 Polymer.dom(this.waveContainer).appendChild(this.wave);
1781 this.resetInteractionState();
1782 }
1783 Ripple.MAX_RADIUS = 300;
1784 Ripple.prototype = {
1785 get recenters() {
1786 return this.element.recenters;
1787 },
1788 get center() {
1789 return this.element.center;
1790 },
1791 get mouseDownElapsed() {
1792 var elapsed;
1793 if (!this.mouseDownStart) {
1794 return 0;
1795 }
1796 elapsed = Utility.now() - this.mouseDownStart;
1797 if (this.mouseUpStart) {
1798 elapsed -= this.mouseUpElapsed;
1799 }
1800 return elapsed;
1801 },
1802 get mouseUpElapsed() {
1803 return this.mouseUpStart ? Utility.now() - this.mouseUpStart : 0;
1804 },
1805 get mouseDownElapsedSeconds() {
1806 return this.mouseDownElapsed / 1e3;
1807 },
1808 get mouseUpElapsedSeconds() {
1809 return this.mouseUpElapsed / 1e3;
1810 },
1811 get mouseInteractionSeconds() {
1812 return this.mouseDownElapsedSeconds + this.mouseUpElapsedSeconds;
1813 },
1814 get initialOpacity() {
1815 return this.element.initialOpacity;
1816 },
1817 get opacityDecayVelocity() {
1818 return this.element.opacityDecayVelocity;
1819 },
1820 get radius() {
1821 var width2 = this.containerMetrics.width * this.containerMetrics.width;
1822 var height2 = this.containerMetrics.height * this.containerMetrics.height;
1823 var waveRadius = Math.min(Math.sqrt(width2 + height2), Ripple.MAX_RADIUS) * 1.1 + 5;
1824 var duration = 1.1 - .2 * (waveRadius / Ripple.MAX_RADIUS);
1825 var timeNow = this.mouseInteractionSeconds / duration;
1826 var size = waveRadius * (1 - Math.pow(80, -timeNow));
1827 return Math.abs(size);
1828 },
1829 get opacity() {
1830 if (!this.mouseUpStart) {
1831 return this.initialOpacity;
1832 }
1833 return Math.max(0, this.initialOpacity - this.mouseUpElapsedSeconds * this .opacityDecayVelocity);
1834 },
1835 get outerOpacity() {
1836 var outerOpacity = this.mouseUpElapsedSeconds * .3;
1837 var waveOpacity = this.opacity;
1838 return Math.max(0, Math.min(outerOpacity, waveOpacity));
1839 },
1840 get isOpacityFullyDecayed() {
1841 return this.opacity < .01 && this.radius >= Math.min(this.maxRadius, Rippl e.MAX_RADIUS);
1842 },
1843 get isRestingAtMaxRadius() {
1844 return this.opacity >= this.initialOpacity && this.radius >= Math.min(this .maxRadius, Ripple.MAX_RADIUS);
1845 },
1846 get isAnimationComplete() {
1847 return this.mouseUpStart ? this.isOpacityFullyDecayed : this.isRestingAtMa xRadius;
1848 },
1849 get translationFraction() {
1850 return Math.min(1, this.radius / this.containerMetrics.size * 2 / Math.sqr t(2));
1851 },
1852 get xNow() {
1853 if (this.xEnd) {
1854 return this.xStart + this.translationFraction * (this.xEnd - this.xStart );
1855 }
1856 return this.xStart;
1857 },
1858 get yNow() {
1859 if (this.yEnd) {
1860 return this.yStart + this.translationFraction * (this.yEnd - this.yStart );
1861 }
1862 return this.yStart;
1863 },
1864 get isMouseDown() {
1865 return this.mouseDownStart && !this.mouseUpStart;
1866 },
1867 resetInteractionState: function() {
1868 this.maxRadius = 0;
1869 this.mouseDownStart = 0;
1870 this.mouseUpStart = 0;
1871 this.xStart = 0;
1872 this.yStart = 0;
1873 this.xEnd = 0;
1874 this.yEnd = 0;
1875 this.slideDistance = 0;
1876 this.containerMetrics = new ElementMetrics(this.element);
1877 },
1878 draw: function() {
1879 var scale;
1880 var translateString;
1881 var dx;
1882 var dy;
1883 this.wave.style.opacity = this.opacity;
1884 scale = this.radius / (this.containerMetrics.size / 2);
1885 dx = this.xNow - this.containerMetrics.width / 2;
1886 dy = this.yNow - this.containerMetrics.height / 2;
1887 this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' + dy + 'px)';
1888 this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy + ' px, 0)';
1889 this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')';
1890 this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)';
1891 },
1892 downAction: function(event) {
1893 var xCenter = this.containerMetrics.width / 2;
1894 var yCenter = this.containerMetrics.height / 2;
1895 this.resetInteractionState();
1896 this.mouseDownStart = Utility.now();
1897 if (this.center) {
1898 this.xStart = xCenter;
1899 this.yStart = yCenter;
1900 this.slideDistance = Utility.distance(this.xStart, this.yStart, this.xEn d, this.yEnd);
1901 } else {
1902 this.xStart = event ? event.detail.x - this.containerMetrics.boundingRec t.left : this.containerMetrics.width / 2;
1903 this.yStart = event ? event.detail.y - this.containerMetrics.boundingRec t.top : this.containerMetrics.height / 2;
1904 }
1905 if (this.recenters) {
1906 this.xEnd = xCenter;
1907 this.yEnd = yCenter;
1908 this.slideDistance = Utility.distance(this.xStart, this.yStart, this.xEn d, this.yEnd);
1909 }
1910 this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom(this.xSt art, this.yStart);
1911 this.waveContainer.style.top = (this.containerMetrics.height - this.contai nerMetrics.size) / 2 + 'px';
1912 this.waveContainer.style.left = (this.containerMetrics.width - this.contai nerMetrics.size) / 2 + 'px';
1913 this.waveContainer.style.width = this.containerMetrics.size + 'px';
1914 this.waveContainer.style.height = this.containerMetrics.size + 'px';
1915 },
1916 upAction: function(event) {
1917 if (!this.isMouseDown) {
1918 return;
1919 }
1920 this.mouseUpStart = Utility.now();
1921 },
1922 remove: function() {
1923 Polymer.dom(this.waveContainer.parentNode).removeChild(this.waveContainer) ;
1924 }
1925 };
1926 Polymer({
1927 is: 'paper-ripple',
1928 behaviors: [ Polymer.IronA11yKeysBehavior ],
1929 properties: {
1930 initialOpacity: {
1931 type: Number,
1932 value: .25
1933 },
1934 opacityDecayVelocity: {
1935 type: Number,
1936 value: .8
1937 },
1938 recenters: {
1939 type: Boolean,
1940 value: false
1941 },
1942 center: {
1943 type: Boolean,
1944 value: false
1945 },
1946 ripples: {
1947 type: Array,
1948 value: function() {
1949 return [];
1950 }
1951 },
1952 animating: {
1953 type: Boolean,
1954 readOnly: true,
1955 reflectToAttribute: true,
1956 value: false
1957 },
1958 holdDown: {
1959 type: Boolean,
1960 value: false,
1961 observer: '_holdDownChanged'
1962 },
1963 noink: {
1964 type: Boolean,
1965 value: false
1966 },
1967 _animating: {
1968 type: Boolean
1969 },
1970 _boundAnimate: {
1971 type: Function,
1972 value: function() {
1973 return this.animate.bind(this);
1974 }
1975 }
1976 },
1977 get target() {
1978 return this.keyEventTarget;
1979 },
1980 keyBindings: {
1981 'enter:keydown': '_onEnterKeydown',
1982 'space:keydown': '_onSpaceKeydown',
1983 'space:keyup': '_onSpaceKeyup'
1984 },
1985 attached: function() {
1986 if (this.parentNode.nodeType == 11) {
1987 this.keyEventTarget = Polymer.dom(this).getOwnerRoot().host;
1988 } else {
1989 this.keyEventTarget = this.parentNode;
1990 }
1991 var keyEventTarget = this.keyEventTarget;
1992 this.listen(keyEventTarget, 'up', 'uiUpAction');
1993 this.listen(keyEventTarget, 'down', 'uiDownAction');
1994 },
1995 detached: function() {
1996 this.unlisten(this.keyEventTarget, 'up', 'uiUpAction');
1997 this.unlisten(this.keyEventTarget, 'down', 'uiDownAction');
1998 this.keyEventTarget = null;
1999 },
2000 get shouldKeepAnimating() {
2001 for (var index = 0; index < this.ripples.length; ++index) {
2002 if (!this.ripples[index].isAnimationComplete) {
2003 return true;
2004 }
2005 }
2006 return false;
2007 },
2008 simulatedRipple: function() {
2009 this.downAction(null);
2010 this.async(function() {
2011 this.upAction();
2012 }, 1);
2013 },
2014 uiDownAction: function(event) {
2015 if (!this.noink) {
2016 this.downAction(event);
2017 }
2018 },
2019 downAction: function(event) {
2020 if (this.holdDown && this.ripples.length > 0) {
2021 return;
2022 }
2023 var ripple = this.addRipple();
2024 ripple.downAction(event);
2025 if (!this._animating) {
2026 this._animating = true;
2027 this.animate();
2028 }
2029 },
2030 uiUpAction: function(event) {
2031 if (!this.noink) {
2032 this.upAction(event);
2033 }
2034 },
2035 upAction: function(event) {
2036 if (this.holdDown) {
2037 return;
2038 }
2039 this.ripples.forEach(function(ripple) {
2040 ripple.upAction(event);
2041 });
2042 this._animating = true;
2043 this.animate();
2044 },
2045 onAnimationComplete: function() {
2046 this._animating = false;
2047 this.$.background.style.backgroundColor = null;
2048 this.fire('transitionend');
2049 },
2050 addRipple: function() {
2051 var ripple = new Ripple(this);
2052 Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);
2053 this.$.background.style.backgroundColor = ripple.color;
2054 this.ripples.push(ripple);
2055 this._setAnimating(true);
2056 return ripple;
2057 },
2058 removeRipple: function(ripple) {
2059 var rippleIndex = this.ripples.indexOf(ripple);
2060 if (rippleIndex < 0) {
2061 return;
2062 }
2063 this.ripples.splice(rippleIndex, 1);
2064 ripple.remove();
2065 if (!this.ripples.length) {
2066 this._setAnimating(false);
2067 }
2068 },
2069 animate: function() {
2070 if (!this._animating) {
2071 return;
2072 }
2073 var index;
2074 var ripple;
2075 for (index = 0; index < this.ripples.length; ++index) {
2076 ripple = this.ripples[index];
2077 ripple.draw();
2078 this.$.background.style.opacity = ripple.outerOpacity;
2079 if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) {
2080 this.removeRipple(ripple);
2081 }
2082 }
2083 if (!this.shouldKeepAnimating && this.ripples.length === 0) {
2084 this.onAnimationComplete();
2085 } else {
2086 window.requestAnimationFrame(this._boundAnimate);
2087 }
2088 },
2089 _onEnterKeydown: function() {
2090 this.uiDownAction();
2091 this.async(this.uiUpAction, 1);
2092 },
2093 _onSpaceKeydown: function() {
2094 this.uiDownAction();
2095 },
2096 _onSpaceKeyup: function() {
2097 this.uiUpAction();
2098 },
2099 _holdDownChanged: function(newVal, oldVal) {
2100 if (oldVal === undefined) {
2101 return;
2102 }
2103 if (newVal) {
2104 this.downAction();
2105 } else {
2106 this.upAction();
2107 }
2108 }
2109 });
2110 })();
2111
2112 Polymer.PaperRippleBehavior = {
2113 properties: {
2114 noink: {
2115 type: Boolean,
2116 observer: '_noinkChanged'
2117 },
2118 _rippleContainer: {
2119 type: Object
2120 }
2121 },
2122 _buttonStateChanged: function() {
2123 if (this.focused) {
2124 this.ensureRipple();
2125 }
2126 },
2127 _downHandler: function(event) {
2128 Polymer.IronButtonStateImpl._downHandler.call(this, event);
2129 if (this.pressed) {
2130 this.ensureRipple(event);
2131 }
2132 },
2133 ensureRipple: function(optTriggeringEvent) {
2134 if (!this.hasRipple()) {
2135 this._ripple = this._createRipple();
2136 this._ripple.noink = this.noink;
2137 var rippleContainer = this._rippleContainer || this.root;
2138 if (rippleContainer) {
2139 Polymer.dom(rippleContainer).appendChild(this._ripple);
2140 }
2141 if (optTriggeringEvent) {
2142 var domContainer = Polymer.dom(this._rippleContainer || this);
2143 var target = Polymer.dom(optTriggeringEvent).rootTarget;
2144 if (domContainer.deepContains(target)) {
2145 this._ripple.uiDownAction(optTriggeringEvent);
2146 }
2147 }
2148 }
2149 },
2150 getRipple: function() {
2151 this.ensureRipple();
2152 return this._ripple;
2153 },
2154 hasRipple: function() {
2155 return Boolean(this._ripple);
2156 },
2157 _createRipple: function() {
2158 return document.createElement('paper-ripple');
2159 },
2160 _noinkChanged: function(noink) {
2161 if (this.hasRipple()) {
2162 this._ripple.noink = noink;
2163 }
2164 }
2165 };
2166
2167 Polymer.PaperInkyFocusBehaviorImpl = {
2168 observers: [ '_focusedChanged(receivedFocusFromKeyboard)' ],
2169 _focusedChanged: function(receivedFocusFromKeyboard) {
2170 if (receivedFocusFromKeyboard) {
2171 this.ensureRipple();
2172 }
2173 if (this.hasRipple()) {
2174 this._ripple.holdDown = receivedFocusFromKeyboard;
2175 }
2176 },
2177 _createRipple: function() {
2178 var ripple = Polymer.PaperRippleBehavior._createRipple();
2179 ripple.id = 'ink';
2180 ripple.setAttribute('center', '');
2181 ripple.classList.add('circle');
2182 return ripple;
2183 }
2184 };
2185
2186 Polymer.PaperInkyFocusBehavior = [ Polymer.IronButtonState, Polymer.IronControlS tate, Polymer.PaperRippleBehavior, Polymer.PaperInkyFocusBehaviorImpl ];
2187
2188 Polymer({
2189 is: 'paper-icon-button',
2190 hostAttributes: {
2191 role: 'button',
2192 tabindex: '0'
2193 },
2194 behaviors: [ Polymer.PaperInkyFocusBehavior ],
2195 properties: {
2196 src: {
2197 type: String
2198 },
2199 icon: {
2200 type: String
2201 },
2202 alt: {
2203 type: String,
2204 observer: "_altChanged"
2205 }
2206 },
2207 _altChanged: function(newValue, oldValue) {
2208 var label = this.getAttribute('aria-label');
2209 if (!label || oldValue == label) {
2210 this.setAttribute('aria-label', newValue);
2211 }
2212 }
2213 });
2214
2215 Polymer({
2216 is: 'iron-iconset-svg',
2217 properties: {
2218 name: {
2219 type: String,
2220 observer: '_nameChanged'
2221 },
2222 size: {
2223 type: Number,
2224 value: 24
2225 }
2226 },
2227 attached: function() {
2228 this.style.display = 'none';
2229 },
2230 getIconNames: function() {
2231 this._icons = this._createIconMap();
2232 return Object.keys(this._icons).map(function(n) {
2233 return this.name + ':' + n;
2234 }, this);
2235 },
2236 applyIcon: function(element, iconName) {
2237 element = element.root || element;
2238 this.removeIcon(element);
2239 var svg = this._cloneIcon(iconName);
2240 if (svg) {
2241 var pde = Polymer.dom(element);
2242 pde.insertBefore(svg, pde.childNodes[0]);
2243 return element._svgIcon = svg;
2244 }
2245 return null;
2246 },
2247 removeIcon: function(element) {
2248 if (element._svgIcon) {
2249 Polymer.dom(element).removeChild(element._svgIcon);
2250 element._svgIcon = null;
2251 }
2252 },
2253 _nameChanged: function() {
2254 new Polymer.IronMeta({
2255 type: 'iconset',
2256 key: this.name,
2257 value: this
2258 });
2259 this.async(function() {
2260 this.fire('iron-iconset-added', this, {
2261 node: window
2262 });
2263 });
2264 },
2265 _createIconMap: function() {
2266 var icons = Object.create(null);
2267 Polymer.dom(this).querySelectorAll('[id]').forEach(function(icon) {
2268 icons[icon.id] = icon;
2269 });
2270 return icons;
2271 },
2272 _cloneIcon: function(id) {
2273 this._icons = this._icons || this._createIconMap();
2274 return this._prepareSvgClone(this._icons[id], this.size);
2275 },
2276 _prepareSvgClone: function(sourceSvg, size) {
2277 if (sourceSvg) {
2278 var content = sourceSvg.cloneNode(true), svg = document.createElementNS('h ttp://www.w3.org/2000/svg', 'svg'), viewBox = content.getAttribute('viewBox') || '0 0 ' + size + ' ' + size;
2279 svg.setAttribute('viewBox', viewBox);
2280 svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
2281 svg.style.cssText = 'pointer-events: none; display: block; width: 100%; he ight: 100%;';
2282 svg.appendChild(content).removeAttribute('id');
2283 return svg;
2284 }
2285 return null;
2286 }
2287 });
2288
2289 // Copyright 2016 The Chromium Authors. All rights reserved. 19 // Copyright 2016 The Chromium Authors. All rights reserved.
2290 // Use of this source code is governed by a BSD-style license that can be 20 // Use of this source code is governed by a BSD-style license that can be
2291 // found in the LICENSE file. 21 // found in the LICENSE file.
2292 Polymer({ 22 Polymer({is:"cr-lazy-render","extends":"template",behaviors:[Polymer.Templatizer ],child_:null,get:function(){if(!this.child_)this.render_();return this.child_}, getIfExists:function(){return this.child_},render_:function(){if(!this.ctor)this .templatize(this);var parentNode=this.parentNode;if(parentNode&&!this.child_){va r instance=this.stamp({});this.child_=instance.root.firstElementChild;parentNode .insertBefore(instance.root,this)}},_forwardParentProp:function(prop,value){if(t his.child_)this.child_._templateInstance[prop]=value},_forwardParentPath:functio n(path,value){if(this.child_)this.child_._templateInstance.notifyPath(path,value ,true)}});(function(){"use strict";Polymer.IronA11yAnnouncer=Polymer({is:"iron-a 11y-announcer",properties:{mode:{type:String,value:"polite"},_text:{type:String, value:""}},created:function(){if(!Polymer.IronA11yAnnouncer.instance){Polymer.Ir onA11yAnnouncer.instance=this}document.body.addEventListener("iron-announce",thi s._onIronAnnounce.bind(this))},announce:function(text){this._text="";this.async( function(){this._text=text},100)},_onIronAnnounce:function(event){if(event.detai l&&event.detail.text){this.announce(event.detail.text)}}});Polymer.IronA11yAnnou ncer.instance=null;Polymer.IronA11yAnnouncer.requestAvailability=function(){if(! Polymer.IronA11yAnnouncer.instance){Polymer.IronA11yAnnouncer.instance=document. createElement("iron-a11y-announcer")}document.body.appendChild(Polymer.IronA11yA nnouncer.instance)}})();Polymer.IronValidatableBehaviorMeta=null;Polymer.IronVal idatableBehavior={properties:{validator:{type:String},invalid:{notify:true,refle ctToAttribute:true,type:Boolean,value:false},_validatorMeta:{type:Object},valida torType:{type:String,value:"validator"},_validator:{type:Object,computed:"__comp uteValidator(validator)"}},observers:["_invalidChanged(invalid)"],registered:fun ction(){Polymer.IronValidatableBehaviorMeta=new Polymer.IronMeta({type:"validato r"})},_invalidChanged:function(){if(this.invalid){this.setAttribute("aria-invali d","true")}else{this.removeAttribute("aria-invalid")}},hasValidator:function(){r eturn this._validator!=null},validate:function(value){this.invalid=!this._getVal idity(value);return!this.invalid},_getValidity:function(value){if(this.hasValida tor()){return this._validator.validate(value)}return true},__computeValidator:fu nction(){return Polymer.IronValidatableBehaviorMeta&&Polymer.IronValidatableBeha viorMeta.byKey(this.validator)}};Polymer({is:"iron-input","extends":"input",beha viors:[Polymer.IronValidatableBehavior],properties:{bindValue:{observer:"_bindVa lueChanged",type:String},preventInvalidInput:{type:Boolean},allowedPattern:{type :String,observer:"_allowedPatternChanged"},_previousValidInput:{type:String,valu e:""},_patternAlreadyChecked:{type:Boolean,value:false}},listeners:{input:"_onIn put",keypress:"_onKeypress"},registered:function(){if(!this._canDispatchEventOnD isabled()){this._origDispatchEvent=this.dispatchEvent;this.dispatchEvent=this._d ispatchEventFirefoxIE}},created:function(){Polymer.IronA11yAnnouncer.requestAvai lability()},_canDispatchEventOnDisabled:function(){var input=document.createElem ent("input");var canDispatch=false;input.disabled=true;input.addEventListener("f eature-check-dispatch-event",function(){canDispatch=true});try{input.dispatchEve nt(new Event("feature-check-dispatch-event"))}catch(e){}return canDispatch},_dis patchEventFirefoxIE:function(){var disabled=this.disabled;this.disabled=false;th is._origDispatchEvent.apply(this,arguments);this.disabled=disabled},get _pattern RegExp(){var pattern;if(this.allowedPattern){pattern=new RegExp(this.allowedPatt ern)}else{switch(this.type){case"number":pattern=/[0-9.,e-]/;break}}return patte rn},ready:function(){this.bindValue=this.value},_bindValueChanged:function(){if( this.value!==this.bindValue){this.value=!(this.bindValue||this.bindValue===0||th is.bindValue===false)?"":this.bindValue}this.fire("bind-value-changed",{value:th is.bindValue})},_allowedPatternChanged:function(){this.preventInvalidInput=this. allowedPattern?true:false},_onInput:function(){if(this.preventInvalidInput&&!thi s._patternAlreadyChecked){var valid=this._checkPatternValidity();if(!valid){this ._announceInvalidCharacter("Invalid string of characters not entered.");this.val ue=this._previousValidInput}}this.bindValue=this.value;this._previousValidInput= this.value;this._patternAlreadyChecked=false},_isPrintable:function(event){var a nyNonPrintable=event.keyCode==8||event.keyCode==9||event.keyCode==13||event.keyC ode==27;var mozNonPrintable=event.keyCode==19||event.keyCode==20||event.keyCode= =45||event.keyCode==46||event.keyCode==144||event.keyCode==145||event.keyCode>32 &&event.keyCode<41||event.keyCode>111&&event.keyCode<124;return!anyNonPrintable& &!(event.charCode==0&&mozNonPrintable)},_onKeypress:function(event){if(!this.pre ventInvalidInput&&this.type!=="number"){return}var regexp=this._patternRegExp;if (!regexp){return}if(event.metaKey||event.ctrlKey||event.altKey)return;this._patt ernAlreadyChecked=true;var thisChar=String.fromCharCode(event.charCode);if(this. _isPrintable(event)&&!regexp.test(thisChar)){event.preventDefault();this._announ ceInvalidCharacter("Invalid character "+thisChar+" not entered.")}},_checkPatter nValidity:function(){var regexp=this._patternRegExp;if(!regexp){return true}for( var i=0;i<this.value.length;i++){if(!regexp.test(this.value[i])){return false}}r eturn true},validate:function(){var valid=this.checkValidity();if(valid){if(this .required&&this.value===""){valid=false}else if(this.hasValidator()){valid=Polym er.IronValidatableBehavior.validate.call(this,this.value)}}this.invalid=!valid;t his.fire("iron-input-validate");return valid},_announceInvalidCharacter:function (message){this.fire("iron-announce",{text:message})}});Polymer({is:"paper-input- container",properties:{noLabelFloat:{type:Boolean,value:false},alwaysFloatLabel: {type:Boolean,value:false},attrForValue:{type:String,value:"bind-value"},autoVal idate:{type:Boolean,value:false},invalid:{observer:"_invalidChanged",type:Boolea n,value:false},focused:{readOnly:true,type:Boolean,value:false,notify:true},_add ons:{type:Array},_inputHasContent:{type:Boolean,value:false},_inputSelector:{typ e:String,value:"input,textarea,.paper-input-input"},_boundOnFocus:{type:Function ,value:function(){return this._onFocus.bind(this)}},_boundOnBlur:{type:Function, value:function(){return this._onBlur.bind(this)}},_boundOnInput:{type:Function,v alue:function(){return this._onInput.bind(this)}},_boundValueChanged:{type:Funct ion,value:function(){return this._onValueChanged.bind(this)}}},listeners:{"addon -attached":"_onAddonAttached","iron-input-validate":"_onIronInputValidate"},get _valueChangedEvent(){return this.attrForValue+"-changed"},get _propertyForValue( ){return Polymer.CaseMap.dashToCamelCase(this.attrForValue)},get _inputElement() {return Polymer.dom(this).querySelector(this._inputSelector)},get _inputElementV alue(){return this._inputElement[this._propertyForValue]||this._inputElement.val ue},ready:function(){if(!this._addons){this._addons=[]}this.addEventListener("fo cus",this._boundOnFocus,true);this.addEventListener("blur",this._boundOnBlur,tru e)},attached:function(){if(this.attrForValue){this._inputElement.addEventListene r(this._valueChangedEvent,this._boundValueChanged)}else{this.addEventListener("i nput",this._onInput)}if(this._inputElementValue!=""){this._handleValueAndAutoVal idate(this._inputElement)}else{this._handleValue(this._inputElement)}},_onAddonA ttached:function(event){if(!this._addons){this._addons=[]}var target=event.targe t;if(this._addons.indexOf(target)===-1){this._addons.push(target);if(this.isAtta ched){this._handleValue(this._inputElement)}}},_onFocus:function(){this._setFocu sed(true)},_onBlur:function(){this._setFocused(false);this._handleValueAndAutoVa lidate(this._inputElement)},_onInput:function(event){this._handleValueAndAutoVal idate(event.target)},_onValueChanged:function(event){this._handleValueAndAutoVal idate(event.target)},_handleValue:function(inputElement){var value=this._inputEl ementValue;if(value||value===0||inputElement.type==="number"&&!inputElement.chec kValidity()){this._inputHasContent=true}else{this._inputHasContent=false}this.up dateAddons({inputElement:inputElement,value:value,invalid:this.invalid})},_handl eValueAndAutoValidate:function(inputElement){if(this.autoValidate){var valid;if( inputElement.validate){valid=inputElement.validate(this._inputElementValue)}else {valid=inputElement.checkValidity()}this.invalid=!valid}this._handleValue(inputE lement)},_onIronInputValidate:function(event){this.invalid=this._inputElement.in valid},_invalidChanged:function(){if(this._addons){this.updateAddons({invalid:th is.invalid})}},updateAddons:function(state){for(var addon,index=0;addon=this._ad dons[index];index++){addon.update(state)}},_computeInputContentClass:function(no LabelFloat,alwaysFloatLabel,focused,invalid,_inputHasContent){var cls="input-con tent";if(!noLabelFloat){var label=this.querySelector("label");if(alwaysFloatLabe l||_inputHasContent){cls+=" label-is-floating";this.$.labelAndInputContainer.sty le.position="static";if(invalid){cls+=" is-invalid"}else if(focused){cls+=" labe l-is-highlighted"}}else{if(label){this.$.labelAndInputContainer.style.position=" relative"}}}else{if(_inputHasContent){cls+=" label-is-hidden"}}return cls},_comp uteUnderlineClass:function(focused,invalid){var cls="underline";if(invalid){cls+ =" is-invalid"}else if(focused){cls+=" is-highlighted"}return cls},_computeAddOn ContentClass:function(focused,invalid){var cls="add-on-content";if(invalid){cls+ =" is-invalid"}else if(focused){cls+=" is-highlighted"}return cls}});Polymer.Pap erSpinnerBehavior={listeners:{animationend:"__reset",webkitAnimationEnd:"__reset "},properties:{active:{type:Boolean,value:false,reflectToAttribute:true,observer :"__activeChanged"},alt:{type:String,value:"loading",observer:"__altChanged"},__ coolingDown:{type:Boolean,value:false}},__computeContainerClasses:function(activ e,coolingDown){return[active||coolingDown?"active":"",coolingDown?"cooldown":""] .join(" ")},__activeChanged:function(active,old){this.__setAriaHidden(!active);t his.__coolingDown=!active&&old},__altChanged:function(alt){if(alt===this.getProp ertyInfo("alt").value){this.alt=this.getAttribute("aria-label")||alt}else{this._ _setAriaHidden(alt==="");this.setAttribute("aria-label",alt)}},__setAriaHidden:f unction(hidden){var attr="aria-hidden";if(hidden){this.setAttribute(attr,"true") }else{this.removeAttribute(attr)}},__reset:function(){this.active=false;this.__c oolingDown=false}};Polymer({is:"paper-spinner-lite",behaviors:[Polymer.PaperSpin nerBehavior]});
2293 is: 'cr-lazy-render',
2294 "extends": 'template',
2295 behaviors: [ Polymer.Templatizer ],
2296 child_: null,
2297 get: function() {
2298 if (!this.child_) this.render_();
2299 return this.child_;
2300 },
2301 getIfExists: function() {
2302 return this.child_;
2303 },
2304 render_: function() {
2305 if (!this.ctor) this.templatize(this);
2306 var parentNode = this.parentNode;
2307 if (parentNode && !this.child_) {
2308 var instance = this.stamp({});
2309 this.child_ = instance.root.firstElementChild;
2310 parentNode.insertBefore(instance.root, this);
2311 }
2312 },
2313 _forwardParentProp: function(prop, value) {
2314 if (this.child_) this.child_._templateInstance[prop] = value;
2315 },
2316 _forwardParentPath: function(path, value) {
2317 if (this.child_) this.child_._templateInstance.notifyPath(path, value, true) ;
2318 }
2319 });
2320
2321 (function() {
2322 'use strict';
2323 Polymer.IronA11yAnnouncer = Polymer({
2324 is: 'iron-a11y-announcer',
2325 properties: {
2326 mode: {
2327 type: String,
2328 value: 'polite'
2329 },
2330 _text: {
2331 type: String,
2332 value: ''
2333 }
2334 },
2335 created: function() {
2336 if (!Polymer.IronA11yAnnouncer.instance) {
2337 Polymer.IronA11yAnnouncer.instance = this;
2338 }
2339 document.body.addEventListener('iron-announce', this._onIronAnnounce.bind( this));
2340 },
2341 announce: function(text) {
2342 this._text = '';
2343 this.async(function() {
2344 this._text = text;
2345 }, 100);
2346 },
2347 _onIronAnnounce: function(event) {
2348 if (event.detail && event.detail.text) {
2349 this.announce(event.detail.text);
2350 }
2351 }
2352 });
2353 Polymer.IronA11yAnnouncer.instance = null;
2354 Polymer.IronA11yAnnouncer.requestAvailability = function() {
2355 if (!Polymer.IronA11yAnnouncer.instance) {
2356 Polymer.IronA11yAnnouncer.instance = document.createElement('iron-a11y-ann ouncer');
2357 }
2358 document.body.appendChild(Polymer.IronA11yAnnouncer.instance);
2359 };
2360 })();
2361
2362 Polymer.IronValidatableBehaviorMeta = null;
2363
2364 Polymer.IronValidatableBehavior = {
2365 properties: {
2366 validator: {
2367 type: String
2368 },
2369 invalid: {
2370 notify: true,
2371 reflectToAttribute: true,
2372 type: Boolean,
2373 value: false
2374 },
2375 _validatorMeta: {
2376 type: Object
2377 },
2378 validatorType: {
2379 type: String,
2380 value: 'validator'
2381 },
2382 _validator: {
2383 type: Object,
2384 computed: '__computeValidator(validator)'
2385 }
2386 },
2387 observers: [ '_invalidChanged(invalid)' ],
2388 registered: function() {
2389 Polymer.IronValidatableBehaviorMeta = new Polymer.IronMeta({
2390 type: 'validator'
2391 });
2392 },
2393 _invalidChanged: function() {
2394 if (this.invalid) {
2395 this.setAttribute('aria-invalid', 'true');
2396 } else {
2397 this.removeAttribute('aria-invalid');
2398 }
2399 },
2400 hasValidator: function() {
2401 return this._validator != null;
2402 },
2403 validate: function(value) {
2404 this.invalid = !this._getValidity(value);
2405 return !this.invalid;
2406 },
2407 _getValidity: function(value) {
2408 if (this.hasValidator()) {
2409 return this._validator.validate(value);
2410 }
2411 return true;
2412 },
2413 __computeValidator: function() {
2414 return Polymer.IronValidatableBehaviorMeta && Polymer.IronValidatableBehavio rMeta.byKey(this.validator);
2415 }
2416 };
2417
2418 Polymer({
2419 is: 'iron-input',
2420 "extends": 'input',
2421 behaviors: [ Polymer.IronValidatableBehavior ],
2422 properties: {
2423 bindValue: {
2424 observer: '_bindValueChanged',
2425 type: String
2426 },
2427 preventInvalidInput: {
2428 type: Boolean
2429 },
2430 allowedPattern: {
2431 type: String,
2432 observer: "_allowedPatternChanged"
2433 },
2434 _previousValidInput: {
2435 type: String,
2436 value: ''
2437 },
2438 _patternAlreadyChecked: {
2439 type: Boolean,
2440 value: false
2441 }
2442 },
2443 listeners: {
2444 input: '_onInput',
2445 keypress: '_onKeypress'
2446 },
2447 registered: function() {
2448 if (!this._canDispatchEventOnDisabled()) {
2449 this._origDispatchEvent = this.dispatchEvent;
2450 this.dispatchEvent = this._dispatchEventFirefoxIE;
2451 }
2452 },
2453 created: function() {
2454 Polymer.IronA11yAnnouncer.requestAvailability();
2455 },
2456 _canDispatchEventOnDisabled: function() {
2457 var input = document.createElement('input');
2458 var canDispatch = false;
2459 input.disabled = true;
2460 input.addEventListener('feature-check-dispatch-event', function() {
2461 canDispatch = true;
2462 });
2463 try {
2464 input.dispatchEvent(new Event('feature-check-dispatch-event'));
2465 } catch (e) {}
2466 return canDispatch;
2467 },
2468 _dispatchEventFirefoxIE: function() {
2469 var disabled = this.disabled;
2470 this.disabled = false;
2471 this._origDispatchEvent.apply(this, arguments);
2472 this.disabled = disabled;
2473 },
2474 get _patternRegExp() {
2475 var pattern;
2476 if (this.allowedPattern) {
2477 pattern = new RegExp(this.allowedPattern);
2478 } else {
2479 switch (this.type) {
2480 case 'number':
2481 pattern = /[0-9.,e-]/;
2482 break;
2483 }
2484 }
2485 return pattern;
2486 },
2487 ready: function() {
2488 this.bindValue = this.value;
2489 },
2490 _bindValueChanged: function() {
2491 if (this.value !== this.bindValue) {
2492 this.value = !(this.bindValue || this.bindValue === 0 || this.bindValue == = false) ? '' : this.bindValue;
2493 }
2494 this.fire('bind-value-changed', {
2495 value: this.bindValue
2496 });
2497 },
2498 _allowedPatternChanged: function() {
2499 this.preventInvalidInput = this.allowedPattern ? true : false;
2500 },
2501 _onInput: function() {
2502 if (this.preventInvalidInput && !this._patternAlreadyChecked) {
2503 var valid = this._checkPatternValidity();
2504 if (!valid) {
2505 this._announceInvalidCharacter('Invalid string of characters not entered .');
2506 this.value = this._previousValidInput;
2507 }
2508 }
2509 this.bindValue = this.value;
2510 this._previousValidInput = this.value;
2511 this._patternAlreadyChecked = false;
2512 },
2513 _isPrintable: function(event) {
2514 var anyNonPrintable = event.keyCode == 8 || event.keyCode == 9 || event.keyC ode == 13 || event.keyCode == 27;
2515 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;
2516 return !anyNonPrintable && !(event.charCode == 0 && mozNonPrintable);
2517 },
2518 _onKeypress: function(event) {
2519 if (!this.preventInvalidInput && this.type !== 'number') {
2520 return;
2521 }
2522 var regexp = this._patternRegExp;
2523 if (!regexp) {
2524 return;
2525 }
2526 if (event.metaKey || event.ctrlKey || event.altKey) return;
2527 this._patternAlreadyChecked = true;
2528 var thisChar = String.fromCharCode(event.charCode);
2529 if (this._isPrintable(event) && !regexp.test(thisChar)) {
2530 event.preventDefault();
2531 this._announceInvalidCharacter('Invalid character ' + thisChar + ' not ent ered.');
2532 }
2533 },
2534 _checkPatternValidity: function() {
2535 var regexp = this._patternRegExp;
2536 if (!regexp) {
2537 return true;
2538 }
2539 for (var i = 0; i < this.value.length; i++) {
2540 if (!regexp.test(this.value[i])) {
2541 return false;
2542 }
2543 }
2544 return true;
2545 },
2546 validate: function() {
2547 var valid = this.checkValidity();
2548 if (valid) {
2549 if (this.required && this.value === '') {
2550 valid = false;
2551 } else if (this.hasValidator()) {
2552 valid = Polymer.IronValidatableBehavior.validate.call(this, this.value);
2553 }
2554 }
2555 this.invalid = !valid;
2556 this.fire('iron-input-validate');
2557 return valid;
2558 },
2559 _announceInvalidCharacter: function(message) {
2560 this.fire('iron-announce', {
2561 text: message
2562 });
2563 }
2564 });
2565
2566 Polymer({
2567 is: 'paper-input-container',
2568 properties: {
2569 noLabelFloat: {
2570 type: Boolean,
2571 value: false
2572 },
2573 alwaysFloatLabel: {
2574 type: Boolean,
2575 value: false
2576 },
2577 attrForValue: {
2578 type: String,
2579 value: 'bind-value'
2580 },
2581 autoValidate: {
2582 type: Boolean,
2583 value: false
2584 },
2585 invalid: {
2586 observer: '_invalidChanged',
2587 type: Boolean,
2588 value: false
2589 },
2590 focused: {
2591 readOnly: true,
2592 type: Boolean,
2593 value: false,
2594 notify: true
2595 },
2596 _addons: {
2597 type: Array
2598 },
2599 _inputHasContent: {
2600 type: Boolean,
2601 value: false
2602 },
2603 _inputSelector: {
2604 type: String,
2605 value: 'input,textarea,.paper-input-input'
2606 },
2607 _boundOnFocus: {
2608 type: Function,
2609 value: function() {
2610 return this._onFocus.bind(this);
2611 }
2612 },
2613 _boundOnBlur: {
2614 type: Function,
2615 value: function() {
2616 return this._onBlur.bind(this);
2617 }
2618 },
2619 _boundOnInput: {
2620 type: Function,
2621 value: function() {
2622 return this._onInput.bind(this);
2623 }
2624 },
2625 _boundValueChanged: {
2626 type: Function,
2627 value: function() {
2628 return this._onValueChanged.bind(this);
2629 }
2630 }
2631 },
2632 listeners: {
2633 'addon-attached': '_onAddonAttached',
2634 'iron-input-validate': '_onIronInputValidate'
2635 },
2636 get _valueChangedEvent() {
2637 return this.attrForValue + '-changed';
2638 },
2639 get _propertyForValue() {
2640 return Polymer.CaseMap.dashToCamelCase(this.attrForValue);
2641 },
2642 get _inputElement() {
2643 return Polymer.dom(this).querySelector(this._inputSelector);
2644 },
2645 get _inputElementValue() {
2646 return this._inputElement[this._propertyForValue] || this._inputElement.valu e;
2647 },
2648 ready: function() {
2649 if (!this._addons) {
2650 this._addons = [];
2651 }
2652 this.addEventListener('focus', this._boundOnFocus, true);
2653 this.addEventListener('blur', this._boundOnBlur, true);
2654 },
2655 attached: function() {
2656 if (this.attrForValue) {
2657 this._inputElement.addEventListener(this._valueChangedEvent, this._boundVa lueChanged);
2658 } else {
2659 this.addEventListener('input', this._onInput);
2660 }
2661 if (this._inputElementValue != '') {
2662 this._handleValueAndAutoValidate(this._inputElement);
2663 } else {
2664 this._handleValue(this._inputElement);
2665 }
2666 },
2667 _onAddonAttached: function(event) {
2668 if (!this._addons) {
2669 this._addons = [];
2670 }
2671 var target = event.target;
2672 if (this._addons.indexOf(target) === -1) {
2673 this._addons.push(target);
2674 if (this.isAttached) {
2675 this._handleValue(this._inputElement);
2676 }
2677 }
2678 },
2679 _onFocus: function() {
2680 this._setFocused(true);
2681 },
2682 _onBlur: function() {
2683 this._setFocused(false);
2684 this._handleValueAndAutoValidate(this._inputElement);
2685 },
2686 _onInput: function(event) {
2687 this._handleValueAndAutoValidate(event.target);
2688 },
2689 _onValueChanged: function(event) {
2690 this._handleValueAndAutoValidate(event.target);
2691 },
2692 _handleValue: function(inputElement) {
2693 var value = this._inputElementValue;
2694 if (value || value === 0 || inputElement.type === 'number' && !inputElement. checkValidity()) {
2695 this._inputHasContent = true;
2696 } else {
2697 this._inputHasContent = false;
2698 }
2699 this.updateAddons({
2700 inputElement: inputElement,
2701 value: value,
2702 invalid: this.invalid
2703 });
2704 },
2705 _handleValueAndAutoValidate: function(inputElement) {
2706 if (this.autoValidate) {
2707 var valid;
2708 if (inputElement.validate) {
2709 valid = inputElement.validate(this._inputElementValue);
2710 } else {
2711 valid = inputElement.checkValidity();
2712 }
2713 this.invalid = !valid;
2714 }
2715 this._handleValue(inputElement);
2716 },
2717 _onIronInputValidate: function(event) {
2718 this.invalid = this._inputElement.invalid;
2719 },
2720 _invalidChanged: function() {
2721 if (this._addons) {
2722 this.updateAddons({
2723 invalid: this.invalid
2724 });
2725 }
2726 },
2727 updateAddons: function(state) {
2728 for (var addon, index = 0; addon = this._addons[index]; index++) {
2729 addon.update(state);
2730 }
2731 },
2732 _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused, i nvalid, _inputHasContent) {
2733 var cls = 'input-content';
2734 if (!noLabelFloat) {
2735 var label = this.querySelector('label');
2736 if (alwaysFloatLabel || _inputHasContent) {
2737 cls += ' label-is-floating';
2738 this.$.labelAndInputContainer.style.position = 'static';
2739 if (invalid) {
2740 cls += ' is-invalid';
2741 } else if (focused) {
2742 cls += " label-is-highlighted";
2743 }
2744 } else {
2745 if (label) {
2746 this.$.labelAndInputContainer.style.position = 'relative';
2747 }
2748 }
2749 } else {
2750 if (_inputHasContent) {
2751 cls += ' label-is-hidden';
2752 }
2753 }
2754 return cls;
2755 },
2756 _computeUnderlineClass: function(focused, invalid) {
2757 var cls = 'underline';
2758 if (invalid) {
2759 cls += ' is-invalid';
2760 } else if (focused) {
2761 cls += ' is-highlighted';
2762 }
2763 return cls;
2764 },
2765 _computeAddOnContentClass: function(focused, invalid) {
2766 var cls = 'add-on-content';
2767 if (invalid) {
2768 cls += ' is-invalid';
2769 } else if (focused) {
2770 cls += ' is-highlighted';
2771 }
2772 return cls;
2773 }
2774 });
2775
2776 Polymer.PaperSpinnerBehavior = {
2777 listeners: {
2778 animationend: '__reset',
2779 webkitAnimationEnd: '__reset'
2780 },
2781 properties: {
2782 active: {
2783 type: Boolean,
2784 value: false,
2785 reflectToAttribute: true,
2786 observer: '__activeChanged'
2787 },
2788 alt: {
2789 type: String,
2790 value: 'loading',
2791 observer: '__altChanged'
2792 },
2793 __coolingDown: {
2794 type: Boolean,
2795 value: false
2796 }
2797 },
2798 __computeContainerClasses: function(active, coolingDown) {
2799 return [ active || coolingDown ? 'active' : '', coolingDown ? 'cooldown' : ' ' ].join(' ');
2800 },
2801 __activeChanged: function(active, old) {
2802 this.__setAriaHidden(!active);
2803 this.__coolingDown = !active && old;
2804 },
2805 __altChanged: function(alt) {
2806 if (alt === this.getPropertyInfo('alt').value) {
2807 this.alt = this.getAttribute('aria-label') || alt;
2808 } else {
2809 this.__setAriaHidden(alt === '');
2810 this.setAttribute('aria-label', alt);
2811 }
2812 },
2813 __setAriaHidden: function(hidden) {
2814 var attr = 'aria-hidden';
2815 if (hidden) {
2816 this.setAttribute(attr, 'true');
2817 } else {
2818 this.removeAttribute(attr);
2819 }
2820 },
2821 __reset: function() {
2822 this.active = false;
2823 this.__coolingDown = false;
2824 }
2825 };
2826
2827 Polymer({
2828 is: 'paper-spinner-lite',
2829 behaviors: [ Polymer.PaperSpinnerBehavior ]
2830 });
2831
2832 // Copyright 2016 The Chromium Authors. All rights reserved. 23 // Copyright 2016 The Chromium Authors. All rights reserved.
2833 // Use of this source code is governed by a BSD-style license that can be 24 // Use of this source code is governed by a BSD-style license that can be
2834 // found in the LICENSE file. 25 // found in the LICENSE file.
2835 var CrSearchFieldBehavior = { 26 var CrSearchFieldBehavior={properties:{label:{type:String,value:""},clearLabel:{ type:String,value:""},showingSearch:{type:Boolean,value:false,notify:true,observ er:"showingSearchChanged_",reflectToAttribute:true},lastValue_:{type:String,valu e:""}},getSearchInput:function(){},getValue:function(){return this.getSearchInpu t().value},setValue:function(value){this.getSearchInput().bindValue=value;this.o nValueChanged_(value)},showAndFocus:function(){this.showingSearch=true;this.focu s_()},focus_:function(){this.getSearchInput().focus()},onSearchTermSearch:functi on(){this.onValueChanged_(this.getValue())},onValueChanged_:function(newValue){i f(newValue==this.lastValue_)return;this.fire("search-changed",newValue);this.las tValue_=newValue},onSearchTermKeydown:function(e){if(e.key=="Escape")this.showin gSearch=false},showingSearchChanged_:function(){if(this.showingSearch){this.focu s_();return}this.setValue("");this.getSearchInput().blur()}};
2836 properties: {
2837 label: {
2838 type: String,
2839 value: ''
2840 },
2841 clearLabel: {
2842 type: String,
2843 value: ''
2844 },
2845 showingSearch: {
2846 type: Boolean,
2847 value: false,
2848 notify: true,
2849 observer: 'showingSearchChanged_',
2850 reflectToAttribute: true
2851 },
2852 lastValue_: {
2853 type: String,
2854 value: ''
2855 }
2856 },
2857 getSearchInput: function() {},
2858 getValue: function() {
2859 return this.getSearchInput().value;
2860 },
2861 setValue: function(value) {
2862 this.getSearchInput().bindValue = value;
2863 this.onValueChanged_(value);
2864 },
2865 showAndFocus: function() {
2866 this.showingSearch = true;
2867 this.focus_();
2868 },
2869 focus_: function() {
2870 this.getSearchInput().focus();
2871 },
2872 onSearchTermSearch: function() {
2873 this.onValueChanged_(this.getValue());
2874 },
2875 onValueChanged_: function(newValue) {
2876 if (newValue == this.lastValue_) return;
2877 this.fire('search-changed', newValue);
2878 this.lastValue_ = newValue;
2879 },
2880 onSearchTermKeydown: function(e) {
2881 if (e.key == 'Escape') this.showingSearch = false;
2882 },
2883 showingSearchChanged_: function() {
2884 if (this.showingSearch) {
2885 this.focus_();
2886 return;
2887 }
2888 this.setValue('');
2889 this.getSearchInput().blur();
2890 }
2891 };
2892
2893 // Copyright 2016 The Chromium Authors. All rights reserved. 27 // Copyright 2016 The Chromium Authors. All rights reserved.
2894 // Use of this source code is governed by a BSD-style license that can be 28 // Use of this source code is governed by a BSD-style license that can be
2895 // found in the LICENSE file. 29 // found in the LICENSE file.
2896 Polymer({ 30 Polymer({is:"cr-toolbar-search-field",behaviors:[CrSearchFieldBehavior],properti es:{narrow:{type:Boolean,reflectToAttribute:true},label:String,clearLabel:String ,spinnerActive:{type:Boolean,reflectToAttribute:true},hasSearchText_:Boolean,isS pinnerShown_:{type:Boolean,computed:"computeIsSpinnerShown_(spinnerActive, showi ngSearch)"}},listeners:{tap:"showSearch_","searchInput.bind-value-changed":"onBi ndValueChanged_"},getSearchInput:function(){return this.$.searchInput},isSearchF ocused:function(){return this.$.searchTerm.focused},computeIconTabIndex_:functio n(narrow){return narrow?0:-1},computeIsSpinnerShown_:function(){return this.spin nerActive&&this.showingSearch},onInputBlur_:function(){if(!this.hasSearchText_)t his.showingSearch=false},onBindValueChanged_:function(){var newValue=this.$.sear chInput.bindValue;this.hasSearchText_=newValue!="";if(newValue!="")this.showingS earch=true},showSearch_:function(e){if(e.target!=this.$.clearSearch)this.showing Search=true},hideSearch_:function(e){this.showingSearch=false;e.stopPropagation( )}});
2897 is: 'cr-toolbar-search-field',
2898 behaviors: [ CrSearchFieldBehavior ],
2899 properties: {
2900 narrow: {
2901 type: Boolean,
2902 reflectToAttribute: true
2903 },
2904 label: String,
2905 clearLabel: String,
2906 spinnerActive: {
2907 type: Boolean,
2908 reflectToAttribute: true
2909 },
2910 hasSearchText_: Boolean,
2911 isSpinnerShown_: {
2912 type: Boolean,
2913 computed: 'computeIsSpinnerShown_(spinnerActive, showingSearch)'
2914 }
2915 },
2916 listeners: {
2917 tap: 'showSearch_',
2918 'searchInput.bind-value-changed': 'onBindValueChanged_'
2919 },
2920 getSearchInput: function() {
2921 return this.$.searchInput;
2922 },
2923 isSearchFocused: function() {
2924 return this.$.searchTerm.focused;
2925 },
2926 computeIconTabIndex_: function(narrow) {
2927 return narrow ? 0 : -1;
2928 },
2929 computeIsSpinnerShown_: function() {
2930 return this.spinnerActive && this.showingSearch;
2931 },
2932 onInputBlur_: function() {
2933 if (!this.hasSearchText_) this.showingSearch = false;
2934 },
2935 onBindValueChanged_: function() {
2936 var newValue = this.$.searchInput.bindValue;
2937 this.hasSearchText_ = newValue != '';
2938 if (newValue != '') this.showingSearch = true;
2939 },
2940 showSearch_: function(e) {
2941 if (e.target != this.$.clearSearch) this.showingSearch = true;
2942 },
2943 hideSearch_: function(e) {
2944 this.showingSearch = false;
2945 e.stopPropagation();
2946 }
2947 });
2948
2949 // Copyright 2016 The Chromium Authors. All rights reserved. 31 // Copyright 2016 The Chromium Authors. All rights reserved.
2950 // Use of this source code is governed by a BSD-style license that can be 32 // Use of this source code is governed by a BSD-style license that can be
2951 // found in the LICENSE file. 33 // found in the LICENSE file.
2952 Polymer({ 34 Polymer({is:"cr-toolbar",properties:{pageName:String,searchPrompt:String,clearLa bel:String,menuLabel:String,menuPromo:String,spinnerActive:Boolean,showMenu:{typ e:Boolean,value:false},showMenuPromo:{type:Boolean,value:false},closeMenuPromo:S tring,narrow_:{type:Boolean,reflectToAttribute:true},showingSearch_:{type:Boolea n,reflectToAttribute:true}},observers:["possiblyShowMenuPromo_(showMenu, showMen uPromo, showingSearch_)"],getSearchField:function(){return this.$.search},onClos ePromoTap_:function(){this.showMenuPromo=false},onMenuTap_:function(){this.fire( "cr-menu-tap");this.onClosePromoTap_()},possiblyShowMenuPromo_:function(){Polyme r.RenderStatus.afterNextRender(this,function(){if(this.showMenu&&this.showMenuPr omo&&!this.showingSearch_){this.$$("#menuPromo").animate({opacity:[0,.9]},{durat ion:500,fill:"forwards"});this.fire("cr-menu-promo-shown")}}.bind(this))},titleI fNotShowMenuPromo_:function(title,showMenuPromo){return showMenuPromo?"":title}} );
2953 is: 'cr-toolbar',
2954 properties: {
2955 pageName: String,
2956 searchPrompt: String,
2957 clearLabel: String,
2958 menuLabel: String,
2959 menuPromo: String,
2960 spinnerActive: Boolean,
2961 showMenu: {
2962 type: Boolean,
2963 value: false
2964 },
2965 showMenuPromo: {
2966 type: Boolean,
2967 value: false
2968 },
2969 closeMenuPromo: String,
2970 narrow_: {
2971 type: Boolean,
2972 reflectToAttribute: true
2973 },
2974 showingSearch_: {
2975 type: Boolean,
2976 reflectToAttribute: true
2977 }
2978 },
2979 observers: [ 'possiblyShowMenuPromo_(showMenu, showMenuPromo, showingSearch_)' ],
2980 getSearchField: function() {
2981 return this.$.search;
2982 },
2983 onClosePromoTap_: function() {
2984 this.showMenuPromo = false;
2985 },
2986 onMenuTap_: function() {
2987 this.fire('cr-menu-tap');
2988 this.onClosePromoTap_();
2989 },
2990 possiblyShowMenuPromo_: function() {
2991 Polymer.RenderStatus.afterNextRender(this, function() {
2992 if (this.showMenu && this.showMenuPromo && !this.showingSearch_) {
2993 this.$$('#menuPromo').animate({
2994 opacity: [ 0, .9 ]
2995 }, {
2996 duration: 500,
2997 fill: 'forwards'
2998 });
2999 this.fire('cr-menu-promo-shown');
3000 }
3001 }.bind(this));
3002 },
3003 titleIfNotShowMenuPromo_: function(title, showMenuPromo) {
3004 return showMenuPromo ? '' : title;
3005 }
3006 });
3007
3008 // Copyright 2016 The Chromium Authors. All rights reserved. 35 // Copyright 2016 The Chromium Authors. All rights reserved.
3009 // Use of this source code is governed by a BSD-style license that can be 36 // Use of this source code is governed by a BSD-style license that can be
3010 // found in the LICENSE file. 37 // found in the LICENSE file.
3011 cr.define('md_history', function() { 38 cr.define("md_history",function(){function BrowserService(){this.pendingDeleteIt ems_=null;this.pendingDeletePromise_=null}BrowserService.prototype={deleteItems: function(items){if(this.pendingDeleteItems_!=null){return new Promise(function(r esolve,reject){reject(items)})}var removalList=items.map(function(item){return{u rl:item.url,timestamps:item.allTimestamps}});this.pendingDeleteItems_=items;this .pendingDeletePromise_=new PromiseResolver;chrome.send("removeVisits",removalLis t);return this.pendingDeletePromise_.promise},removeBookmark:function(url){chrom e.send("removeBookmark",[url])},openForeignSessionAllTabs:function(sessionTag){c hrome.send("openForeignSession",[sessionTag])},openForeignSessionTab:function(se ssionTag,windowId,tabId,e){chrome.send("openForeignSession",[sessionTag,String(w indowId),String(tabId),e.button||0,e.altKey,e.ctrlKey,e.metaKey,e.shiftKey])},de leteForeignSession:function(sessionTag){chrome.send("deleteForeignSession",[sess ionTag])},openClearBrowsingData:function(){chrome.send("clearBrowsingData")},rec ordHistogram:function(histogram,value,max){chrome.send("metricsHandler:recordInH istogram",[histogram,value,max])},recordAction:function(action){if(action.indexO f("_")==-1)action="HistoryPage_"+action;chrome.send("metricsHandler:recordAction ",[action])},resolveDelete_:function(successful){if(this.pendingDeleteItems_==nu ll||this.pendingDeletePromise_==null){return}if(successful)this.pendingDeletePro mise_.resolve(this.pendingDeleteItems_);else this.pendingDeletePromise_.reject(t his.pendingDeleteItems_);this.pendingDeleteItems_=null;this.pendingDeletePromise _=null},menuPromoShown:function(){chrome.send("menuPromoShown")}};cr.addSingleto nGetter(BrowserService);return{BrowserService:BrowserService}});function deleteC omplete(){md_history.BrowserService.getInstance().resolveDelete_(true)}function deleteFailed(){md_history.BrowserService.getInstance().resolveDelete_(false)}
3012 function BrowserService() {
3013 this.pendingDeleteItems_ = null;
3014 this.pendingDeletePromise_ = null;
3015 }
3016 BrowserService.prototype = {
3017 deleteItems: function(items) {
3018 if (this.pendingDeleteItems_ != null) {
3019 return new Promise(function(resolve, reject) {
3020 reject(items);
3021 });
3022 }
3023 var removalList = items.map(function(item) {
3024 return {
3025 url: item.url,
3026 timestamps: item.allTimestamps
3027 };
3028 });
3029 this.pendingDeleteItems_ = items;
3030 this.pendingDeletePromise_ = new PromiseResolver();
3031 chrome.send('removeVisits', removalList);
3032 return this.pendingDeletePromise_.promise;
3033 },
3034 removeBookmark: function(url) {
3035 chrome.send('removeBookmark', [ url ]);
3036 },
3037 openForeignSessionAllTabs: function(sessionTag) {
3038 chrome.send('openForeignSession', [ sessionTag ]);
3039 },
3040 openForeignSessionTab: function(sessionTag, windowId, tabId, e) {
3041 chrome.send('openForeignSession', [ sessionTag, String(windowId), String(t abId), e.button || 0, e.altKey, e.ctrlKey, e.metaKey, e.shiftKey ]);
3042 },
3043 deleteForeignSession: function(sessionTag) {
3044 chrome.send('deleteForeignSession', [ sessionTag ]);
3045 },
3046 openClearBrowsingData: function() {
3047 chrome.send('clearBrowsingData');
3048 },
3049 recordHistogram: function(histogram, value, max) {
3050 chrome.send('metricsHandler:recordInHistogram', [ histogram, value, max ]) ;
3051 },
3052 recordAction: function(action) {
3053 if (action.indexOf('_') == -1) action = 'HistoryPage_' + action;
3054 chrome.send('metricsHandler:recordAction', [ action ]);
3055 },
3056 resolveDelete_: function(successful) {
3057 if (this.pendingDeleteItems_ == null || this.pendingDeletePromise_ == null ) {
3058 return;
3059 }
3060 if (successful) this.pendingDeletePromise_.resolve(this.pendingDeleteItems _); else this.pendingDeletePromise_.reject(this.pendingDeleteItems_);
3061 this.pendingDeleteItems_ = null;
3062 this.pendingDeletePromise_ = null;
3063 },
3064 menuPromoShown: function() {
3065 chrome.send('menuPromoShown');
3066 }
3067 };
3068 cr.addSingletonGetter(BrowserService);
3069 return {
3070 BrowserService: BrowserService
3071 };
3072 });
3073
3074 function deleteComplete() {
3075 md_history.BrowserService.getInstance().resolveDelete_(true);
3076 }
3077
3078 function deleteFailed() {
3079 md_history.BrowserService.getInstance().resolveDelete_(false);
3080 }
3081
3082 // Copyright 2015 The Chromium Authors. All rights reserved. 39 // Copyright 2015 The Chromium Authors. All rights reserved.
3083 // Use of this source code is governed by a BSD-style license that can be 40 // Use of this source code is governed by a BSD-style license that can be
3084 // found in the LICENSE file. 41 // found in the LICENSE file.
3085 Polymer({ 42 Polymer({is:"history-toolbar",properties:{count:{type:Number,value:0,observer:"c hangeToolbarView_"},itemsSelected_:{type:Boolean,value:false,reflectToAttribute: true},searchTerm:{type:String,observer:"searchTermChanged_",notify:true},spinner Active:{type:Boolean,value:false},hasDrawer:{type:Boolean,observer:"hasDrawerCha nged_",reflectToAttribute:true},showSyncNotice:Boolean,isGroupedMode:{type:Boole an,reflectToAttribute:true},groupedRange:{type:Number,value:0,reflectToAttribute :true,notify:true},queryStartTime:String,queryEndTime:String,showMenuPromo_:{typ e:Boolean,value:function(){return loadTimeData.getBoolean("showMenuPromo")}}},ge t searchField(){return this.$["main-toolbar"].getSearchField()},showSearchField: function(){this.searchField.showAndFocus()},changeToolbarView_:function(){this.i temsSelected_=this.count>0},searchTermChanged_:function(){if(this.searchField.ge tValue()!=this.searchTerm){this.searchField.showAndFocus();this.searchField.setV alue(this.searchTerm)}},onMenuPromoShown_:function(){md_history.BrowserService.g etInstance().menuPromoShown()},onSearchChanged_:function(event){this.searchTerm= event.detail},onInfoButtonTap_:function(){var dropdown=this.$.syncNotice.get();d ropdown.positionTarget=this.$$("#info-button-icon");if(dropdown.style.display==" none")dropdown.open()},onClearSelectionTap_:function(){this.fire("unselect-all") },onDeleteTap_:function(){this.fire("delete-selected")},deletingAllowed_:functio n(){return loadTimeData.getBoolean("allowDeletingHistory")},numberOfItemsSelecte d_:function(count){return count>0?loadTimeData.getStringF("itemsSelected",count) :""},getHistoryInterval_:function(queryStartTime,queryEndTime){return loadTimeDa ta.getStringF("historyInterval",queryStartTime,queryEndTime)},hasDrawerChanged_: function(){this.updateStyles()}});(function(){var IOS=navigator.userAgent.match( /iP(?:hone|ad;(?: U;)? CPU) OS (\d+)/);var IOS_TOUCH_SCROLLING=IOS&&IOS[1]>=8;va r DEFAULT_PHYSICAL_COUNT=3;var HIDDEN_Y="-10000px";var DEFAULT_GRID_SIZE=200;var SECRET_TABINDEX=-100;Polymer({is:"iron-list",properties:{items:{type:Array},max PhysicalCount:{type:Number,value:500},as:{type:String,value:"item"},indexAs:{typ e:String,value:"index"},selectedAs:{type:String,value:"selected"},grid:{type:Boo lean,value:false,reflectToAttribute:true},selectionEnabled:{type:Boolean,value:f alse},selectedItem:{type:Object,notify:true},selectedItems:{type:Object,notify:t rue},multiSelection:{type:Boolean,value:false}},observers:["_itemsChanged(items. *)","_selectionEnabledChanged(selectionEnabled)","_multiSelectionChanged(multiSe lection)","_setOverflow(scrollTarget)"],behaviors:[Polymer.Templatizer,Polymer.I ronResizableBehavior,Polymer.IronA11yKeysBehavior,Polymer.IronScrollTargetBehavi or],keyBindings:{up:"_didMoveUp",down:"_didMoveDown",enter:"_didEnter"},_ratio:. 5,_scrollerPaddingTop:0,_scrollPosition:0,_physicalSize:0,_physicalAverage:0,_ph ysicalAverageCount:0,_physicalTop:0,_virtualCount:0,_physicalIndexForKey:null,_e stScrollHeight:0,_scrollHeight:0,_viewportHeight:0,_viewportWidth:0,_physicalIte ms:null,_physicalSizes:null,_firstVisibleIndexVal:null,_lastVisibleIndexVal:null ,_collection:null,_maxPages:3,_focusedItem:null,_focusedIndex:-1,_offscreenFocus edItem:null,_focusBackfillItem:null,_itemsPerRow:1,_itemWidth:0,_rowHeight:0,_te mplateCost:0,get _physicalBottom(){return this._physicalTop+this._physicalSize}, get _scrollBottom(){return this._scrollPosition+this._viewportHeight},get _virtu alEnd(){return this._virtualStart+this._physicalCount-1},get _hiddenContentSize( ){var size=this.grid?this._physicalRows*this._rowHeight:this._physicalSize;retur n size-this._viewportHeight},get _maxScrollTop(){return this._estScrollHeight-th is._viewportHeight+this._scrollerPaddingTop},_minVirtualStart:0,get _maxVirtualS tart(){return Math.max(0,this._virtualCount-this._physicalCount)},_virtualStartV al:0,set _virtualStart(val){this._virtualStartVal=Math.min(this._maxVirtualStart ,Math.max(this._minVirtualStart,val))},get _virtualStart(){return this._virtualS tartVal||0},_physicalStartVal:0,set _physicalStart(val){this._physicalStartVal=v al%this._physicalCount;if(this._physicalStartVal<0){this._physicalStartVal=this. _physicalCount+this._physicalStartVal}this._physicalEnd=(this._physicalStart+thi s._physicalCount-1)%this._physicalCount},get _physicalStart(){return this._physi calStartVal||0},_physicalCountVal:0,set _physicalCount(val){this._physicalCountV al=val;this._physicalEnd=(this._physicalStart+this._physicalCount-1)%this._physi calCount},get _physicalCount(){return this._physicalCountVal},_physicalEnd:0,get _optPhysicalSize(){if(this.grid){return this._estRowsInView*this._rowHeight*thi s._maxPages}return this._viewportHeight*this._maxPages},get _optPhysicalCount(){ return this._estRowsInView*this._itemsPerRow*this._maxPages},get _isVisible(){re turn Boolean(this.offsetWidth||this.offsetHeight)},get firstVisibleIndex(){if(th is._firstVisibleIndexVal===null){var physicalOffset=Math.floor(this._physicalTop +this._scrollerPaddingTop);this._firstVisibleIndexVal=this._iterateItems(functio n(pidx,vidx){physicalOffset+=this._getPhysicalSizeIncrement(pidx);if(physicalOff set>this._scrollPosition){return this.grid?vidx-vidx%this._itemsPerRow:vidx}if(t his.grid&&this._virtualCount-1===vidx){return vidx-vidx%this._itemsPerRow}})||0} return this._firstVisibleIndexVal},get lastVisibleIndex(){if(this._lastVisibleIn dexVal===null){if(this.grid){var lastIndex=this.firstVisibleIndex+this._estRowsI nView*this._itemsPerRow-1;this._lastVisibleIndexVal=Math.min(this._virtualCount, lastIndex)}else{var physicalOffset=this._physicalTop;this._iterateItems(function (pidx,vidx){if(physicalOffset<this._scrollBottom){this._lastVisibleIndexVal=vidx }else{return true}physicalOffset+=this._getPhysicalSizeIncrement(pidx)})}}return this._lastVisibleIndexVal},get _defaultScrollTarget(){return this},get _virtual RowCount(){return Math.ceil(this._virtualCount/this._itemsPerRow)},get _estRowsI nView(){return Math.ceil(this._viewportHeight/this._rowHeight)},get _physicalRow s(){return Math.ceil(this._physicalCount/this._itemsPerRow)},ready:function(){th is.addEventListener("focus",this._didFocus.bind(this),true)},attached:function() {this.updateViewportBoundaries();if(this._physicalCount===0){this._debounceTempl ate(this._render)}this.listen(this,"iron-resize","_resizeHandler")},detached:fun ction(){this.unlisten(this,"iron-resize","_resizeHandler")},_setOverflow:functio n(scrollTarget){this.style.webkitOverflowScrolling=scrollTarget===this?"touch":" ";this.style.overflow=scrollTarget===this?"auto":""},updateViewportBoundaries:fu nction(){this._scrollerPaddingTop=this.scrollTarget===this?0:parseInt(window.get ComputedStyle(this)["padding-top"],10);this._viewportHeight=this._scrollTargetHe ight;if(this.grid){this._updateGridMetrics()}},_scrollHandler:function(){var scr ollTop=Math.max(0,Math.min(this._maxScrollTop,this._scrollTop));var delta=scroll Top-this._scrollPosition;var tileHeight,tileTop,kth,recycledTileSet,scrollBottom ,physicalBottom;var ratio=this._ratio;var recycledTiles=0;var hiddenContentSize= this._hiddenContentSize;var currentRatio=ratio;var movingUp=[];this._scrollPosit ion=scrollTop;this._firstVisibleIndexVal=null;this._lastVisibleIndexVal=null;scr ollBottom=this._scrollBottom;physicalBottom=this._physicalBottom;if(Math.abs(del ta)>this._physicalSize){this._physicalTop+=delta;recycledTiles=Math.round(delta/ this._physicalAverage)}else if(delta<0){var topSpace=scrollTop-this._physicalTop ;var virtualStart=this._virtualStart;recycledTileSet=[];kth=this._physicalEnd;cu rrentRatio=topSpace/hiddenContentSize;while(currentRatio<ratio&&recycledTiles<th is._physicalCount&&virtualStart-recycledTiles>0&&physicalBottom-this._getPhysica lSizeIncrement(kth)>scrollBottom){tileHeight=this._getPhysicalSizeIncrement(kth) ;currentRatio+=tileHeight/hiddenContentSize;physicalBottom-=tileHeight;recycledT ileSet.push(kth);recycledTiles++;kth=kth===0?this._physicalCount-1:kth-1}movingU p=recycledTileSet;recycledTiles=-recycledTiles}else if(delta>0){var bottomSpace= physicalBottom-scrollBottom;var virtualEnd=this._virtualEnd;var lastVirtualItemI ndex=this._virtualCount-1;recycledTileSet=[];kth=this._physicalStart;currentRati o=bottomSpace/hiddenContentSize;while(currentRatio<ratio&&recycledTiles<this._ph ysicalCount&&virtualEnd+recycledTiles<lastVirtualItemIndex&&this._physicalTop+th is._getPhysicalSizeIncrement(kth)<scrollTop){tileHeight=this._getPhysicalSizeInc rement(kth);currentRatio+=tileHeight/hiddenContentSize;this._physicalTop+=tileHe ight;recycledTileSet.push(kth);recycledTiles++;kth=(kth+1)%this._physicalCount}} if(recycledTiles===0){if(physicalBottom<scrollBottom||this._physicalTop>scrollTo p){this._increasePoolIfNeeded()}}else{this._virtualStart=this._virtualStart+recy cledTiles;this._physicalStart=this._physicalStart+recycledTiles;this._update(rec ycledTileSet,movingUp)}},_update:function(itemSet,movingUp){this._manageFocus(); this._assignModels(itemSet);this._updateMetrics(itemSet);if(movingUp){while(movi ngUp.length){var idx=movingUp.pop();this._physicalTop-=this._getPhysicalSizeIncr ement(idx)}}this._positionItems();this._updateScrollerSize();this._increasePoolI fNeeded()},_createPool:function(size){var physicalItems=new Array(size);this._en sureTemplatized();for(var i=0;i<size;i++){var inst=this.stamp(null);physicalItem s[i]=inst.root.querySelector("*");Polymer.dom(this).appendChild(inst.root)}retur n physicalItems},_increasePoolIfNeeded:function(){if(this._viewportHeight===0){r eturn false}var self=this;var isClientFull=this._physicalBottom>=this._scrollBot tom&&this._physicalTop<=this._scrollPosition;if(this._physicalSize>=this._optPhy sicalSize&&isClientFull){return false}var maxPoolSize=Math.round(this._physicalC ount*.5);if(!isClientFull){this._debounceTemplate(this._increasePool.bind(this,m axPoolSize));return true}this._yield(function(){self._increasePool(Math.min(maxP oolSize,Math.max(1,Math.round(50/self._templateCost))))});return true},_yield:fu nction(cb){var g=window;var handle=g.requestIdleCallback?g.requestIdleCallback(c b):g.setTimeout(cb,16);Polymer.dom.addDebouncer({complete:function(){g.cancelIdl eCallback?g.cancelIdleCallback(handle):g.clearTimeout(handle);cb()}})},_increase Pool:function(missingItems){var nextPhysicalCount=Math.min(this._physicalCount+m issingItems,this._virtualCount-this._virtualStart,Math.max(this.maxPhysicalCount ,DEFAULT_PHYSICAL_COUNT));var prevPhysicalCount=this._physicalCount;var delta=ne xtPhysicalCount-prevPhysicalCount;var ts=window.performance.now();if(delta<=0){r eturn}[].push.apply(this._physicalItems,this._createPool(delta));[].push.apply(t his._physicalSizes,new Array(delta));this._physicalCount=prevPhysicalCount+delta ;if(this._physicalStart>this._physicalEnd&&this._isIndexRendered(this._focusedIn dex)&&this._getPhysicalIndex(this._focusedIndex)<this._physicalEnd){this._physic alStart=this._physicalStart+delta}this._update();this._templateCost=(window.perf ormance.now()-ts)/delta},_render:function(){if(this.isAttached&&this._isVisible) {if(this._physicalCount===0){this._increasePool(DEFAULT_PHYSICAL_COUNT)}else{thi s._update()}}},_ensureTemplatized:function(){if(!this.ctor){var props={};props._ _key__=true;props[this.as]=true;props[this.indexAs]=true;props[this.selectedAs]= true;props.tabIndex=true;this._instanceProps=props;this._userTemplate=Polymer.do m(this).querySelector("template");if(this._userTemplate){this.templatize(this._u serTemplate)}else{console.warn("iron-list requires a template to be provided in light-dom")}}},_getStampedChildren:function(){return this._physicalItems},_forwa rdInstancePath:function(inst,path,value){if(path.indexOf(this.as+".")===0){this. notifyPath("items."+inst.__key__+"."+path.slice(this.as.length+1),value)}},_forw ardParentProp:function(prop,value){if(this._physicalItems){this._physicalItems.f orEach(function(item){item._templateInstance[prop]=value},this)}},_forwardParent Path:function(path,value){if(this._physicalItems){this._physicalItems.forEach(fu nction(item){item._templateInstance.notifyPath(path,value,true)},this)}},_forwar dItemPath:function(path,value){if(!this._physicalIndexForKey){return}var dot=pat h.indexOf(".");var key=path.substring(0,dot<0?path.length:dot);var idx=this._phy sicalIndexForKey[key];var offscreenItem=this._offscreenFocusedItem;var el=offscr eenItem&&offscreenItem._templateInstance.__key__===key?offscreenItem:this._physi calItems[idx];if(!el||el._templateInstance.__key__!==key){return}if(dot>=0){path =this.as+"."+path.substring(dot+1);el._templateInstance.notifyPath(path,value,tr ue)}else{var currentItem=el._templateInstance[this.as];if(Array.isArray(this.sel ectedItems)){for(var i=0;i<this.selectedItems.length;i++){if(this.selectedItems[ i]===currentItem){this.set("selectedItems."+i,value);break}}}else if(this.select edItem===currentItem){this.set("selectedItem",value)}el._templateInstance[this.a s]=value}},_itemsChanged:function(change){if(change.path==="items"){this._virtua lStart=0;this._physicalTop=0;this._virtualCount=this.items?this.items.length:0;t his._collection=this.items?Polymer.Collection.get(this.items):null;this._physica lIndexForKey={};this._firstVisibleIndexVal=null;this._lastVisibleIndexVal=null;t his._physicalCount=this._physicalCount||0;this._physicalItems=this._physicalItem s||[];this._physicalSizes=this._physicalSizes||[];this._physicalStart=0;this._re setScrollPosition(0);this._removeFocusedItem();this._debounceTemplate(this._rend er)}else if(change.path==="items.splices"){this._adjustVirtualIndex(change.value .indexSplices);this._virtualCount=this.items?this.items.length:0;this._debounceT emplate(this._render)}else{this._forwardItemPath(change.path.split(".").slice(1) .join("."),change.value)}},_adjustVirtualIndex:function(splices){splices.forEach (function(splice){splice.removed.forEach(this._removeItem,this);if(splice.index< this._virtualStart){var delta=Math.max(splice.addedCount-splice.removed.length,s plice.index-this._virtualStart);this._virtualStart=this._virtualStart+delta;if(t his._focusedIndex>=0){this._focusedIndex=this._focusedIndex+delta}}},this)},_rem oveItem:function(item){this.$.selector.deselect(item);if(this._focusedItem&&this ._focusedItem._templateInstance[this.as]===item){this._removeFocusedItem()}},_it erateItems:function(fn,itemSet){var pidx,vidx,rtn,i;if(arguments.length===2&&ite mSet){for(i=0;i<itemSet.length;i++){pidx=itemSet[i];vidx=this._computeVidx(pidx) ;if((rtn=fn.call(this,pidx,vidx))!=null){return rtn}}}else{pidx=this._physicalSt art;vidx=this._virtualStart;for(;pidx<this._physicalCount;pidx++,vidx++){if((rtn =fn.call(this,pidx,vidx))!=null){return rtn}}for(pidx=0;pidx<this._physicalStart ;pidx++,vidx++){if((rtn=fn.call(this,pidx,vidx))!=null){return rtn}}}},_computeV idx:function(pidx){if(pidx>=this._physicalStart){return this._virtualStart+(pidx -this._physicalStart)}return this._virtualStart+(this._physicalCount-this._physi calStart)+pidx},_assignModels:function(itemSet){this._iterateItems(function(pidx ,vidx){var el=this._physicalItems[pidx];var inst=el._templateInstance;var item=t his.items&&this.items[vidx];if(item!=null){inst[this.as]=item;inst.__key__=this. _collection.getKey(item);inst[this.selectedAs]=this.$.selector.isSelected(item); inst[this.indexAs]=vidx;inst.tabIndex=this._focusedIndex===vidx?0:-1;this._physi calIndexForKey[inst.__key__]=pidx;el.removeAttribute("hidden")}else{inst.__key__ =null;el.setAttribute("hidden","")}},itemSet)},_updateMetrics:function(itemSet){ Polymer.dom.flush();var newPhysicalSize=0;var oldPhysicalSize=0;var prevAvgCount =this._physicalAverageCount;var prevPhysicalAvg=this._physicalAverage;this._iter ateItems(function(pidx,vidx){oldPhysicalSize+=this._physicalSizes[pidx]||0;this. _physicalSizes[pidx]=this._physicalItems[pidx].offsetHeight;newPhysicalSize+=thi s._physicalSizes[pidx];this._physicalAverageCount+=this._physicalSizes[pidx]?1:0 },itemSet);this._viewportHeight=this._scrollTargetHeight;if(this.grid){this._upd ateGridMetrics();this._physicalSize=Math.ceil(this._physicalCount/this._itemsPer Row)*this._rowHeight}else{this._physicalSize=this._physicalSize+newPhysicalSize- oldPhysicalSize}if(this._physicalAverageCount!==prevAvgCount){this._physicalAver age=Math.round((prevPhysicalAvg*prevAvgCount+newPhysicalSize)/this._physicalAver ageCount)}},_updateGridMetrics:function(){this._viewportWidth=this.$.items.offse tWidth;this._itemWidth=this._physicalCount>0?this._physicalItems[0].getBoundingC lientRect().width:DEFAULT_GRID_SIZE;this._rowHeight=this._physicalCount>0?this._ physicalItems[0].offsetHeight:DEFAULT_GRID_SIZE;this._itemsPerRow=this._itemWidt h?Math.floor(this._viewportWidth/this._itemWidth):this._itemsPerRow},_positionIt ems:function(){this._adjustScrollPosition();var y=this._physicalTop;if(this.grid ){var totalItemWidth=this._itemsPerRow*this._itemWidth;var rowOffset=(this._view portWidth-totalItemWidth)/2;this._iterateItems(function(pidx,vidx){var modulus=v idx%this._itemsPerRow;var x=Math.floor(modulus*this._itemWidth+rowOffset);this.t ranslate3d(x+"px",y+"px",0,this._physicalItems[pidx]);if(this._shouldRenderNextR ow(vidx)){y+=this._rowHeight}})}else{this._iterateItems(function(pidx,vidx){this .translate3d(0,y+"px",0,this._physicalItems[pidx]);y+=this._physicalSizes[pidx]} )}},_getPhysicalSizeIncrement:function(pidx){if(!this.grid){return this._physica lSizes[pidx]}if(this._computeVidx(pidx)%this._itemsPerRow!==this._itemsPerRow-1) {return 0}return this._rowHeight},_shouldRenderNextRow:function(vidx){return vid x%this._itemsPerRow===this._itemsPerRow-1},_adjustScrollPosition:function(){var deltaHeight=this._virtualStart===0?this._physicalTop:Math.min(this._scrollPositi on+this._physicalTop,0);if(deltaHeight){this._physicalTop=this._physicalTop-delt aHeight;if(!IOS_TOUCH_SCROLLING&&this._physicalTop!==0){this._resetScrollPositio n(this._scrollTop-deltaHeight)}}},_resetScrollPosition:function(pos){if(this.scr ollTarget){this._scrollTop=pos;this._scrollPosition=this._scrollTop}},_updateScr ollerSize:function(forceUpdate){if(this.grid){this._estScrollHeight=this._virtua lRowCount*this._rowHeight}else{this._estScrollHeight=this._physicalBottom+Math.m ax(this._virtualCount-this._physicalCount-this._virtualStart,0)*this._physicalAv erage}forceUpdate=forceUpdate||this._scrollHeight===0;forceUpdate=forceUpdate||t his._scrollPosition>=this._estScrollHeight-this._physicalSize;forceUpdate=forceU pdate||this.grid&&this.$.items.style.height<this._estScrollHeight;if(forceUpdate ||Math.abs(this._estScrollHeight-this._scrollHeight)>=this._optPhysicalSize){thi s.$.items.style.height=this._estScrollHeight+"px";this._scrollHeight=this._estSc rollHeight}},scrollToItem:function(item){return this.scrollToIndex(this.items.in dexOf(item))},scrollToIndex:function(idx){if(typeof idx!=="number"||idx<0||idx>t his.items.length-1){return}Polymer.dom.flush();if(this._physicalCount===0){retur n}idx=Math.min(Math.max(idx,0),this._virtualCount-1);if(!this._isIndexRendered(i dx)||idx>=this._maxVirtualStart){this._virtualStart=this.grid?idx-this._itemsPer Row*2:idx-1}this._manageFocus();this._assignModels();this._updateMetrics();this. _physicalTop=Math.floor(this._virtualStart/this._itemsPerRow)*this._physicalAver age;var currentTopItem=this._physicalStart;var currentVirtualItem=this._virtualS tart;var targetOffsetTop=0;var hiddenContentSize=this._hiddenContentSize;while(c urrentVirtualItem<idx&&targetOffsetTop<=hiddenContentSize){targetOffsetTop=targe tOffsetTop+this._getPhysicalSizeIncrement(currentTopItem);currentTopItem=(curren tTopItem+1)%this._physicalCount;currentVirtualItem++}this._updateScrollerSize(tr ue);this._positionItems();this._resetScrollPosition(this._physicalTop+this._scro llerPaddingTop+targetOffsetTop);this._increasePoolIfNeeded();this._firstVisibleI ndexVal=null;this._lastVisibleIndexVal=null},_resetAverage:function(){this._phys icalAverage=0;this._physicalAverageCount=0},_resizeHandler:function(){if(IOS&&Ma th.abs(this._viewportHeight-this._scrollTargetHeight)<100){return}Polymer.dom.ad dDebouncer(this.debounce("_debounceTemplate",function(){this.updateViewportBound aries();this._render();if(this._physicalCount>0&&this._isVisible){this._resetAve rage();this.scrollToIndex(this.firstVisibleIndex)}}.bind(this),1))},_getModelFro mItem:function(item){var key=this._collection.getKey(item);var pidx=this._physic alIndexForKey[key];if(pidx!=null){return this._physicalItems[pidx]._templateInst ance}return null},_getNormalizedItem:function(item){if(this._collection.getKey(i tem)===undefined){if(typeof item==="number"){item=this.items[item];if(!item){thr ow new RangeError("<item> not found")}return item}throw new TypeError("<item> sh ould be a valid item")}return item},selectItem:function(item){item=this._getNorm alizedItem(item);var model=this._getModelFromItem(item);if(!this.multiSelection& &this.selectedItem){this.deselectItem(this.selectedItem)}if(model){model[this.se lectedAs]=true}this.$.selector.select(item);this.updateSizeForItem(item)},desele ctItem:function(item){item=this._getNormalizedItem(item);var model=this._getMode lFromItem(item);if(model){model[this.selectedAs]=false}this.$.selector.deselect( item);this.updateSizeForItem(item)},toggleSelectionForItem:function(item){item=t his._getNormalizedItem(item);if(this.$.selector.isSelected(item)){this.deselectI tem(item)}else{this.selectItem(item)}},clearSelection:function(){function unsele ct(item){var model=this._getModelFromItem(item);if(model){model[this.selectedAs] =false}}if(Array.isArray(this.selectedItems)){this.selectedItems.forEach(unselec t,this)}else if(this.selectedItem){unselect.call(this,this.selectedItem)}this.$. selector.clearSelection()},_selectionEnabledChanged:function(selectionEnabled){v ar handler=selectionEnabled?this.listen:this.unlisten;handler.call(this,this,"ta p","_selectionHandler")},_selectionHandler:function(e){var model=this.modelForEl ement(e.target);if(!model){return}var modelTabIndex,activeElTabIndex;var target= Polymer.dom(e).path[0];var activeEl=Polymer.dom(this.domHost?this.domHost.root:d ocument).activeElement;var physicalItem=this._physicalItems[this._getPhysicalInd ex(model[this.indexAs])];if(target.localName==="input"||target.localName==="butt on"||target.localName==="select"){return}modelTabIndex=model.tabIndex;model.tabI ndex=SECRET_TABINDEX;activeElTabIndex=activeEl?activeEl.tabIndex:-1;model.tabInd ex=modelTabIndex;if(activeEl&&physicalItem!==activeEl&&physicalItem.contains(act iveEl)&&activeElTabIndex!==SECRET_TABINDEX){return}this.toggleSelectionForItem(m odel[this.as])},_multiSelectionChanged:function(multiSelection){this.clearSelect ion();this.$.selector.multi=multiSelection},updateSizeForItem:function(item){ite m=this._getNormalizedItem(item);var key=this._collection.getKey(item);var pidx=t his._physicalIndexForKey[key];if(pidx!=null){this._updateMetrics([pidx]);this._p ositionItems()}},_manageFocus:function(){var fidx=this._focusedIndex;if(fidx>=0& &fidx<this._virtualCount){if(this._isIndexRendered(fidx)){this._restoreFocusedIt em()}else{this._createFocusBackfillItem()}}else if(this._virtualCount>0&&this._p hysicalCount>0){this._focusedIndex=this._virtualStart;this._focusedItem=this._ph ysicalItems[this._physicalStart]}},_isIndexRendered:function(idx){return idx>=th is._virtualStart&&idx<=this._virtualEnd},_isIndexVisible:function(idx){return id x>=this.firstVisibleIndex&&idx<=this.lastVisibleIndex},_getPhysicalIndex:functio n(idx){return this._physicalIndexForKey[this._collection.getKey(this._getNormali zedItem(idx))]},_focusPhysicalItem:function(idx){if(idx<0||idx>=this._virtualCou nt){return}this._restoreFocusedItem();if(!this._isIndexRendered(idx)){this.scrol lToIndex(idx)}var physicalItem=this._physicalItems[this._getPhysicalIndex(idx)]; var model=physicalItem._templateInstance;var focusable;model.tabIndex=SECRET_TAB INDEX;if(physicalItem.tabIndex===SECRET_TABINDEX){focusable=physicalItem}if(!foc usable){focusable=Polymer.dom(physicalItem).querySelector('[tabindex="'+SECRET_T ABINDEX+'"]')}model.tabIndex=0;this._focusedIndex=idx;focusable&&focusable.focus ()},_removeFocusedItem:function(){if(this._offscreenFocusedItem){Polymer.dom(thi s).removeChild(this._offscreenFocusedItem)}this._offscreenFocusedItem=null;this. _focusBackfillItem=null;this._focusedItem=null;this._focusedIndex=-1},_createFoc usBackfillItem:function(){var pidx,fidx=this._focusedIndex;if(this._offscreenFoc usedItem||fidx<0){return}if(!this._focusBackfillItem){var stampedTemplate=this.s tamp(null);this._focusBackfillItem=stampedTemplate.root.querySelector("*");Polym er.dom(this).appendChild(stampedTemplate.root)}pidx=this._getPhysicalIndex(fidx) ;if(pidx!=null){this._offscreenFocusedItem=this._physicalItems[pidx];this._physi calItems[pidx]=this._focusBackfillItem;this.translate3d(0,HIDDEN_Y,0,this._offsc reenFocusedItem)}},_restoreFocusedItem:function(){var pidx,fidx=this._focusedInd ex;if(!this._offscreenFocusedItem||this._focusedIndex<0){return}this._assignMode ls();pidx=this._getPhysicalIndex(fidx);if(pidx!=null){this._focusBackfillItem=th is._physicalItems[pidx];this._physicalItems[pidx]=this._offscreenFocusedItem;thi s._offscreenFocusedItem=null;this.translate3d(0,HIDDEN_Y,0,this._focusBackfillIt em)}},_didFocus:function(e){var targetModel=this.modelForElement(e.target);var f ocusedModel=this._focusedItem?this._focusedItem._templateInstance:null;var hasOf fscreenFocusedItem=this._offscreenFocusedItem!==null;var fidx=this._focusedIndex ;if(!targetModel||!focusedModel){return}if(focusedModel===targetModel){if(!this. _isIndexVisible(fidx)){this.scrollToIndex(fidx)}}else{this._restoreFocusedItem() ;focusedModel.tabIndex=-1;targetModel.tabIndex=0;fidx=targetModel[this.indexAs]; this._focusedIndex=fidx;this._focusedItem=this._physicalItems[this._getPhysicalI ndex(fidx)];if(hasOffscreenFocusedItem&&!this._offscreenFocusedItem){this._updat e()}}},_didMoveUp:function(){this._focusPhysicalItem(this._focusedIndex-1)},_did MoveDown:function(e){e.detail.keyboardEvent.preventDefault();this._focusPhysical Item(this._focusedIndex+1)},_didEnter:function(e){this._focusPhysicalItem(this._ focusedIndex);this._selectionHandler(e.detail.keyboardEvent)}})})();Polymer({is: "iron-scroll-threshold",properties:{upperThreshold:{type:Number,value:100},lower Threshold:{type:Number,value:100},upperTriggered:{type:Boolean,value:false,notif y:true,readOnly:true},lowerTriggered:{type:Boolean,value:false,notify:true,readO nly:true},horizontal:{type:Boolean,value:false}},behaviors:[Polymer.IronScrollTa rgetBehavior],observers:["_setOverflow(scrollTarget)","_initCheck(horizontal, is Attached)"],get _defaultScrollTarget(){return this},_setOverflow:function(scroll Target){this.style.overflow=scrollTarget===this?"auto":""},_scrollHandler:functi on(){var THROTTLE_THRESHOLD=200;if(!this.isDebouncerActive("_checkTheshold")){th is.debounce("_checkTheshold",function(){this.checkScrollThesholds()},THROTTLE_TH RESHOLD)}},_initCheck:function(horizontal,isAttached){if(isAttached){this.deboun ce("_init",function(){this.clearTriggers();this.checkScrollThesholds()})}},check ScrollThesholds:function(){if(!this.scrollTarget||this.lowerTriggered&&this.uppe rTriggered){return}var upperScrollValue=this.horizontal?this._scrollLeft:this._s crollTop;var lowerScrollValue=this.horizontal?this.scrollTarget.scrollWidth-this ._scrollTargetWidth-this._scrollLeft:this.scrollTarget.scrollHeight-this._scroll TargetHeight-this._scrollTop;if(upperScrollValue<=this.upperThreshold&&!this.upp erTriggered){this._setUpperTriggered(true);this.fire("upper-threshold")}if(lower ScrollValue<=this.lowerThreshold&&!this.lowerTriggered){this._setLowerTriggered( true);this.fire("lower-threshold")}},clearTriggers:function(){this._setUpperTrig gered(false);this._setLowerTriggered(false)}});
3086 is: 'history-toolbar',
3087 properties: {
3088 count: {
3089 type: Number,
3090 value: 0,
3091 observer: 'changeToolbarView_'
3092 },
3093 itemsSelected_: {
3094 type: Boolean,
3095 value: false,
3096 reflectToAttribute: true
3097 },
3098 searchTerm: {
3099 type: String,
3100 observer: 'searchTermChanged_',
3101 notify: true
3102 },
3103 spinnerActive: {
3104 type: Boolean,
3105 value: false
3106 },
3107 hasDrawer: {
3108 type: Boolean,
3109 observer: 'hasDrawerChanged_',
3110 reflectToAttribute: true
3111 },
3112 showSyncNotice: Boolean,
3113 isGroupedMode: {
3114 type: Boolean,
3115 reflectToAttribute: true
3116 },
3117 groupedRange: {
3118 type: Number,
3119 value: 0,
3120 reflectToAttribute: true,
3121 notify: true
3122 },
3123 queryStartTime: String,
3124 queryEndTime: String,
3125 showMenuPromo_: {
3126 type: Boolean,
3127 value: function() {
3128 return loadTimeData.getBoolean('showMenuPromo');
3129 }
3130 }
3131 },
3132 get searchField() {
3133 return this.$['main-toolbar'].getSearchField();
3134 },
3135 showSearchField: function() {
3136 this.searchField.showAndFocus();
3137 },
3138 changeToolbarView_: function() {
3139 this.itemsSelected_ = this.count > 0;
3140 },
3141 searchTermChanged_: function() {
3142 if (this.searchField.getValue() != this.searchTerm) {
3143 this.searchField.showAndFocus();
3144 this.searchField.setValue(this.searchTerm);
3145 }
3146 },
3147 onMenuPromoShown_: function() {
3148 md_history.BrowserService.getInstance().menuPromoShown();
3149 },
3150 onSearchChanged_: function(event) {
3151 this.searchTerm = event.detail;
3152 },
3153 onInfoButtonTap_: function() {
3154 var dropdown = this.$.syncNotice.get();
3155 dropdown.positionTarget = this.$$('#info-button-icon');
3156 if (dropdown.style.display == 'none') dropdown.open();
3157 },
3158 onClearSelectionTap_: function() {
3159 this.fire('unselect-all');
3160 },
3161 onDeleteTap_: function() {
3162 this.fire('delete-selected');
3163 },
3164 deletingAllowed_: function() {
3165 return loadTimeData.getBoolean('allowDeletingHistory');
3166 },
3167 numberOfItemsSelected_: function(count) {
3168 return count > 0 ? loadTimeData.getStringF('itemsSelected', count) : '';
3169 },
3170 getHistoryInterval_: function(queryStartTime, queryEndTime) {
3171 return loadTimeData.getStringF('historyInterval', queryStartTime, queryEndTi me);
3172 },
3173 hasDrawerChanged_: function() {
3174 this.updateStyles();
3175 }
3176 });
3177
3178 (function() {
3179 var IOS = navigator.userAgent.match(/iP(?:hone|ad;(?: U;)? CPU) OS (\d+)/);
3180 var IOS_TOUCH_SCROLLING = IOS && IOS[1] >= 8;
3181 var DEFAULT_PHYSICAL_COUNT = 3;
3182 var HIDDEN_Y = '-10000px';
3183 var DEFAULT_GRID_SIZE = 200;
3184 var SECRET_TABINDEX = -100;
3185 Polymer({
3186 is: 'iron-list',
3187 properties: {
3188 items: {
3189 type: Array
3190 },
3191 maxPhysicalCount: {
3192 type: Number,
3193 value: 500
3194 },
3195 as: {
3196 type: String,
3197 value: 'item'
3198 },
3199 indexAs: {
3200 type: String,
3201 value: 'index'
3202 },
3203 selectedAs: {
3204 type: String,
3205 value: 'selected'
3206 },
3207 grid: {
3208 type: Boolean,
3209 value: false,
3210 reflectToAttribute: true
3211 },
3212 selectionEnabled: {
3213 type: Boolean,
3214 value: false
3215 },
3216 selectedItem: {
3217 type: Object,
3218 notify: true
3219 },
3220 selectedItems: {
3221 type: Object,
3222 notify: true
3223 },
3224 multiSelection: {
3225 type: Boolean,
3226 value: false
3227 }
3228 },
3229 observers: [ '_itemsChanged(items.*)', '_selectionEnabledChanged(selectionEn abled)', '_multiSelectionChanged(multiSelection)', '_setOverflow(scrollTarget)' ],
3230 behaviors: [ Polymer.Templatizer, Polymer.IronResizableBehavior, Polymer.Iro nA11yKeysBehavior, Polymer.IronScrollTargetBehavior ],
3231 keyBindings: {
3232 up: '_didMoveUp',
3233 down: '_didMoveDown',
3234 enter: '_didEnter'
3235 },
3236 _ratio: .5,
3237 _scrollerPaddingTop: 0,
3238 _scrollPosition: 0,
3239 _physicalSize: 0,
3240 _physicalAverage: 0,
3241 _physicalAverageCount: 0,
3242 _physicalTop: 0,
3243 _virtualCount: 0,
3244 _physicalIndexForKey: null,
3245 _estScrollHeight: 0,
3246 _scrollHeight: 0,
3247 _viewportHeight: 0,
3248 _viewportWidth: 0,
3249 _physicalItems: null,
3250 _physicalSizes: null,
3251 _firstVisibleIndexVal: null,
3252 _lastVisibleIndexVal: null,
3253 _collection: null,
3254 _maxPages: 3,
3255 _focusedItem: null,
3256 _focusedIndex: -1,
3257 _offscreenFocusedItem: null,
3258 _focusBackfillItem: null,
3259 _itemsPerRow: 1,
3260 _itemWidth: 0,
3261 _rowHeight: 0,
3262 _templateCost: 0,
3263 get _physicalBottom() {
3264 return this._physicalTop + this._physicalSize;
3265 },
3266 get _scrollBottom() {
3267 return this._scrollPosition + this._viewportHeight;
3268 },
3269 get _virtualEnd() {
3270 return this._virtualStart + this._physicalCount - 1;
3271 },
3272 get _hiddenContentSize() {
3273 var size = this.grid ? this._physicalRows * this._rowHeight : this._physic alSize;
3274 return size - this._viewportHeight;
3275 },
3276 get _maxScrollTop() {
3277 return this._estScrollHeight - this._viewportHeight + this._scrollerPaddin gTop;
3278 },
3279 _minVirtualStart: 0,
3280 get _maxVirtualStart() {
3281 return Math.max(0, this._virtualCount - this._physicalCount);
3282 },
3283 _virtualStartVal: 0,
3284 set _virtualStart(val) {
3285 this._virtualStartVal = Math.min(this._maxVirtualStart, Math.max(this._min VirtualStart, val));
3286 },
3287 get _virtualStart() {
3288 return this._virtualStartVal || 0;
3289 },
3290 _physicalStartVal: 0,
3291 set _physicalStart(val) {
3292 this._physicalStartVal = val % this._physicalCount;
3293 if (this._physicalStartVal < 0) {
3294 this._physicalStartVal = this._physicalCount + this._physicalStartVal;
3295 }
3296 this._physicalEnd = (this._physicalStart + this._physicalCount - 1) % this ._physicalCount;
3297 },
3298 get _physicalStart() {
3299 return this._physicalStartVal || 0;
3300 },
3301 _physicalCountVal: 0,
3302 set _physicalCount(val) {
3303 this._physicalCountVal = val;
3304 this._physicalEnd = (this._physicalStart + this._physicalCount - 1) % this ._physicalCount;
3305 },
3306 get _physicalCount() {
3307 return this._physicalCountVal;
3308 },
3309 _physicalEnd: 0,
3310 get _optPhysicalSize() {
3311 if (this.grid) {
3312 return this._estRowsInView * this._rowHeight * this._maxPages;
3313 }
3314 return this._viewportHeight * this._maxPages;
3315 },
3316 get _optPhysicalCount() {
3317 return this._estRowsInView * this._itemsPerRow * this._maxPages;
3318 },
3319 get _isVisible() {
3320 return Boolean(this.offsetWidth || this.offsetHeight);
3321 },
3322 get firstVisibleIndex() {
3323 if (this._firstVisibleIndexVal === null) {
3324 var physicalOffset = Math.floor(this._physicalTop + this._scrollerPaddin gTop);
3325 this._firstVisibleIndexVal = this._iterateItems(function(pidx, vidx) {
3326 physicalOffset += this._getPhysicalSizeIncrement(pidx);
3327 if (physicalOffset > this._scrollPosition) {
3328 return this.grid ? vidx - vidx % this._itemsPerRow : vidx;
3329 }
3330 if (this.grid && this._virtualCount - 1 === vidx) {
3331 return vidx - vidx % this._itemsPerRow;
3332 }
3333 }) || 0;
3334 }
3335 return this._firstVisibleIndexVal;
3336 },
3337 get lastVisibleIndex() {
3338 if (this._lastVisibleIndexVal === null) {
3339 if (this.grid) {
3340 var lastIndex = this.firstVisibleIndex + this._estRowsInView * this._i temsPerRow - 1;
3341 this._lastVisibleIndexVal = Math.min(this._virtualCount, lastIndex);
3342 } else {
3343 var physicalOffset = this._physicalTop;
3344 this._iterateItems(function(pidx, vidx) {
3345 if (physicalOffset < this._scrollBottom) {
3346 this._lastVisibleIndexVal = vidx;
3347 } else {
3348 return true;
3349 }
3350 physicalOffset += this._getPhysicalSizeIncrement(pidx);
3351 });
3352 }
3353 }
3354 return this._lastVisibleIndexVal;
3355 },
3356 get _defaultScrollTarget() {
3357 return this;
3358 },
3359 get _virtualRowCount() {
3360 return Math.ceil(this._virtualCount / this._itemsPerRow);
3361 },
3362 get _estRowsInView() {
3363 return Math.ceil(this._viewportHeight / this._rowHeight);
3364 },
3365 get _physicalRows() {
3366 return Math.ceil(this._physicalCount / this._itemsPerRow);
3367 },
3368 ready: function() {
3369 this.addEventListener('focus', this._didFocus.bind(this), true);
3370 },
3371 attached: function() {
3372 this.updateViewportBoundaries();
3373 if (this._physicalCount === 0) {
3374 this._debounceTemplate(this._render);
3375 }
3376 this.listen(this, 'iron-resize', '_resizeHandler');
3377 },
3378 detached: function() {
3379 this.unlisten(this, 'iron-resize', '_resizeHandler');
3380 },
3381 _setOverflow: function(scrollTarget) {
3382 this.style.webkitOverflowScrolling = scrollTarget === this ? 'touch' : '';
3383 this.style.overflow = scrollTarget === this ? 'auto' : '';
3384 },
3385 updateViewportBoundaries: function() {
3386 this._scrollerPaddingTop = this.scrollTarget === this ? 0 : parseInt(windo w.getComputedStyle(this)['padding-top'], 10);
3387 this._viewportHeight = this._scrollTargetHeight;
3388 if (this.grid) {
3389 this._updateGridMetrics();
3390 }
3391 },
3392 _scrollHandler: function() {
3393 var scrollTop = Math.max(0, Math.min(this._maxScrollTop, this._scrollTop)) ;
3394 var delta = scrollTop - this._scrollPosition;
3395 var tileHeight, tileTop, kth, recycledTileSet, scrollBottom, physicalBotto m;
3396 var ratio = this._ratio;
3397 var recycledTiles = 0;
3398 var hiddenContentSize = this._hiddenContentSize;
3399 var currentRatio = ratio;
3400 var movingUp = [];
3401 this._scrollPosition = scrollTop;
3402 this._firstVisibleIndexVal = null;
3403 this._lastVisibleIndexVal = null;
3404 scrollBottom = this._scrollBottom;
3405 physicalBottom = this._physicalBottom;
3406 if (Math.abs(delta) > this._physicalSize) {
3407 this._physicalTop += delta;
3408 recycledTiles = Math.round(delta / this._physicalAverage);
3409 } else if (delta < 0) {
3410 var topSpace = scrollTop - this._physicalTop;
3411 var virtualStart = this._virtualStart;
3412 recycledTileSet = [];
3413 kth = this._physicalEnd;
3414 currentRatio = topSpace / hiddenContentSize;
3415 while (currentRatio < ratio && recycledTiles < this._physicalCount && vi rtualStart - recycledTiles > 0 && physicalBottom - this._getPhysicalSizeIncremen t(kth) > scrollBottom) {
3416 tileHeight = this._getPhysicalSizeIncrement(kth);
3417 currentRatio += tileHeight / hiddenContentSize;
3418 physicalBottom -= tileHeight;
3419 recycledTileSet.push(kth);
3420 recycledTiles++;
3421 kth = kth === 0 ? this._physicalCount - 1 : kth - 1;
3422 }
3423 movingUp = recycledTileSet;
3424 recycledTiles = -recycledTiles;
3425 } else if (delta > 0) {
3426 var bottomSpace = physicalBottom - scrollBottom;
3427 var virtualEnd = this._virtualEnd;
3428 var lastVirtualItemIndex = this._virtualCount - 1;
3429 recycledTileSet = [];
3430 kth = this._physicalStart;
3431 currentRatio = bottomSpace / hiddenContentSize;
3432 while (currentRatio < ratio && recycledTiles < this._physicalCount && vi rtualEnd + recycledTiles < lastVirtualItemIndex && this._physicalTop + this._get PhysicalSizeIncrement(kth) < scrollTop) {
3433 tileHeight = this._getPhysicalSizeIncrement(kth);
3434 currentRatio += tileHeight / hiddenContentSize;
3435 this._physicalTop += tileHeight;
3436 recycledTileSet.push(kth);
3437 recycledTiles++;
3438 kth = (kth + 1) % this._physicalCount;
3439 }
3440 }
3441 if (recycledTiles === 0) {
3442 if (physicalBottom < scrollBottom || this._physicalTop > scrollTop) {
3443 this._increasePoolIfNeeded();
3444 }
3445 } else {
3446 this._virtualStart = this._virtualStart + recycledTiles;
3447 this._physicalStart = this._physicalStart + recycledTiles;
3448 this._update(recycledTileSet, movingUp);
3449 }
3450 },
3451 _update: function(itemSet, movingUp) {
3452 this._manageFocus();
3453 this._assignModels(itemSet);
3454 this._updateMetrics(itemSet);
3455 if (movingUp) {
3456 while (movingUp.length) {
3457 var idx = movingUp.pop();
3458 this._physicalTop -= this._getPhysicalSizeIncrement(idx);
3459 }
3460 }
3461 this._positionItems();
3462 this._updateScrollerSize();
3463 this._increasePoolIfNeeded();
3464 },
3465 _createPool: function(size) {
3466 var physicalItems = new Array(size);
3467 this._ensureTemplatized();
3468 for (var i = 0; i < size; i++) {
3469 var inst = this.stamp(null);
3470 physicalItems[i] = inst.root.querySelector('*');
3471 Polymer.dom(this).appendChild(inst.root);
3472 }
3473 return physicalItems;
3474 },
3475 _increasePoolIfNeeded: function() {
3476 if (this._viewportHeight === 0) {
3477 return false;
3478 }
3479 var self = this;
3480 var isClientFull = this._physicalBottom >= this._scrollBottom && this._phy sicalTop <= this._scrollPosition;
3481 if (this._physicalSize >= this._optPhysicalSize && isClientFull) {
3482 return false;
3483 }
3484 var maxPoolSize = Math.round(this._physicalCount * .5);
3485 if (!isClientFull) {
3486 this._debounceTemplate(this._increasePool.bind(this, maxPoolSize));
3487 return true;
3488 }
3489 this._yield(function() {
3490 self._increasePool(Math.min(maxPoolSize, Math.max(1, Math.round(50 / sel f._templateCost))));
3491 });
3492 return true;
3493 },
3494 _yield: function(cb) {
3495 var g = window;
3496 var handle = g.requestIdleCallback ? g.requestIdleCallback(cb) : g.setTime out(cb, 16);
3497 Polymer.dom.addDebouncer({
3498 complete: function() {
3499 g.cancelIdleCallback ? g.cancelIdleCallback(handle) : g.clearTimeout(h andle);
3500 cb();
3501 }
3502 });
3503 },
3504 _increasePool: function(missingItems) {
3505 var nextPhysicalCount = Math.min(this._physicalCount + missingItems, this. _virtualCount - this._virtualStart, Math.max(this.maxPhysicalCount, DEFAULT_PHYS ICAL_COUNT));
3506 var prevPhysicalCount = this._physicalCount;
3507 var delta = nextPhysicalCount - prevPhysicalCount;
3508 var ts = window.performance.now();
3509 if (delta <= 0) {
3510 return;
3511 }
3512 [].push.apply(this._physicalItems, this._createPool(delta));
3513 [].push.apply(this._physicalSizes, new Array(delta));
3514 this._physicalCount = prevPhysicalCount + delta;
3515 if (this._physicalStart > this._physicalEnd && this._isIndexRendered(this. _focusedIndex) && this._getPhysicalIndex(this._focusedIndex) < this._physicalEnd ) {
3516 this._physicalStart = this._physicalStart + delta;
3517 }
3518 this._update();
3519 this._templateCost = (window.performance.now() - ts) / delta;
3520 },
3521 _render: function() {
3522 if (this.isAttached && this._isVisible) {
3523 if (this._physicalCount === 0) {
3524 this._increasePool(DEFAULT_PHYSICAL_COUNT);
3525 } else {
3526 this._update();
3527 }
3528 }
3529 },
3530 _ensureTemplatized: function() {
3531 if (!this.ctor) {
3532 var props = {};
3533 props.__key__ = true;
3534 props[this.as] = true;
3535 props[this.indexAs] = true;
3536 props[this.selectedAs] = true;
3537 props.tabIndex = true;
3538 this._instanceProps = props;
3539 this._userTemplate = Polymer.dom(this).querySelector('template');
3540 if (this._userTemplate) {
3541 this.templatize(this._userTemplate);
3542 } else {
3543 console.warn('iron-list requires a template to be provided in light-do m');
3544 }
3545 }
3546 },
3547 _getStampedChildren: function() {
3548 return this._physicalItems;
3549 },
3550 _forwardInstancePath: function(inst, path, value) {
3551 if (path.indexOf(this.as + '.') === 0) {
3552 this.notifyPath('items.' + inst.__key__ + '.' + path.slice(this.as.lengt h + 1), value);
3553 }
3554 },
3555 _forwardParentProp: function(prop, value) {
3556 if (this._physicalItems) {
3557 this._physicalItems.forEach(function(item) {
3558 item._templateInstance[prop] = value;
3559 }, this);
3560 }
3561 },
3562 _forwardParentPath: function(path, value) {
3563 if (this._physicalItems) {
3564 this._physicalItems.forEach(function(item) {
3565 item._templateInstance.notifyPath(path, value, true);
3566 }, this);
3567 }
3568 },
3569 _forwardItemPath: function(path, value) {
3570 if (!this._physicalIndexForKey) {
3571 return;
3572 }
3573 var dot = path.indexOf('.');
3574 var key = path.substring(0, dot < 0 ? path.length : dot);
3575 var idx = this._physicalIndexForKey[key];
3576 var offscreenItem = this._offscreenFocusedItem;
3577 var el = offscreenItem && offscreenItem._templateInstance.__key__ === key ? offscreenItem : this._physicalItems[idx];
3578 if (!el || el._templateInstance.__key__ !== key) {
3579 return;
3580 }
3581 if (dot >= 0) {
3582 path = this.as + '.' + path.substring(dot + 1);
3583 el._templateInstance.notifyPath(path, value, true);
3584 } else {
3585 var currentItem = el._templateInstance[this.as];
3586 if (Array.isArray(this.selectedItems)) {
3587 for (var i = 0; i < this.selectedItems.length; i++) {
3588 if (this.selectedItems[i] === currentItem) {
3589 this.set('selectedItems.' + i, value);
3590 break;
3591 }
3592 }
3593 } else if (this.selectedItem === currentItem) {
3594 this.set('selectedItem', value);
3595 }
3596 el._templateInstance[this.as] = value;
3597 }
3598 },
3599 _itemsChanged: function(change) {
3600 if (change.path === 'items') {
3601 this._virtualStart = 0;
3602 this._physicalTop = 0;
3603 this._virtualCount = this.items ? this.items.length : 0;
3604 this._collection = this.items ? Polymer.Collection.get(this.items) : nul l;
3605 this._physicalIndexForKey = {};
3606 this._firstVisibleIndexVal = null;
3607 this._lastVisibleIndexVal = null;
3608 this._physicalCount = this._physicalCount || 0;
3609 this._physicalItems = this._physicalItems || [];
3610 this._physicalSizes = this._physicalSizes || [];
3611 this._physicalStart = 0;
3612 this._resetScrollPosition(0);
3613 this._removeFocusedItem();
3614 this._debounceTemplate(this._render);
3615 } else if (change.path === 'items.splices') {
3616 this._adjustVirtualIndex(change.value.indexSplices);
3617 this._virtualCount = this.items ? this.items.length : 0;
3618 this._debounceTemplate(this._render);
3619 } else {
3620 this._forwardItemPath(change.path.split('.').slice(1).join('.'), change. value);
3621 }
3622 },
3623 _adjustVirtualIndex: function(splices) {
3624 splices.forEach(function(splice) {
3625 splice.removed.forEach(this._removeItem, this);
3626 if (splice.index < this._virtualStart) {
3627 var delta = Math.max(splice.addedCount - splice.removed.length, splice .index - this._virtualStart);
3628 this._virtualStart = this._virtualStart + delta;
3629 if (this._focusedIndex >= 0) {
3630 this._focusedIndex = this._focusedIndex + delta;
3631 }
3632 }
3633 }, this);
3634 },
3635 _removeItem: function(item) {
3636 this.$.selector.deselect(item);
3637 if (this._focusedItem && this._focusedItem._templateInstance[this.as] === item) {
3638 this._removeFocusedItem();
3639 }
3640 },
3641 _iterateItems: function(fn, itemSet) {
3642 var pidx, vidx, rtn, i;
3643 if (arguments.length === 2 && itemSet) {
3644 for (i = 0; i < itemSet.length; i++) {
3645 pidx = itemSet[i];
3646 vidx = this._computeVidx(pidx);
3647 if ((rtn = fn.call(this, pidx, vidx)) != null) {
3648 return rtn;
3649 }
3650 }
3651 } else {
3652 pidx = this._physicalStart;
3653 vidx = this._virtualStart;
3654 for (;pidx < this._physicalCount; pidx++, vidx++) {
3655 if ((rtn = fn.call(this, pidx, vidx)) != null) {
3656 return rtn;
3657 }
3658 }
3659 for (pidx = 0; pidx < this._physicalStart; pidx++, vidx++) {
3660 if ((rtn = fn.call(this, pidx, vidx)) != null) {
3661 return rtn;
3662 }
3663 }
3664 }
3665 },
3666 _computeVidx: function(pidx) {
3667 if (pidx >= this._physicalStart) {
3668 return this._virtualStart + (pidx - this._physicalStart);
3669 }
3670 return this._virtualStart + (this._physicalCount - this._physicalStart) + pidx;
3671 },
3672 _assignModels: function(itemSet) {
3673 this._iterateItems(function(pidx, vidx) {
3674 var el = this._physicalItems[pidx];
3675 var inst = el._templateInstance;
3676 var item = this.items && this.items[vidx];
3677 if (item != null) {
3678 inst[this.as] = item;
3679 inst.__key__ = this._collection.getKey(item);
3680 inst[this.selectedAs] = this.$.selector.isSelected(item);
3681 inst[this.indexAs] = vidx;
3682 inst.tabIndex = this._focusedIndex === vidx ? 0 : -1;
3683 this._physicalIndexForKey[inst.__key__] = pidx;
3684 el.removeAttribute('hidden');
3685 } else {
3686 inst.__key__ = null;
3687 el.setAttribute('hidden', '');
3688 }
3689 }, itemSet);
3690 },
3691 _updateMetrics: function(itemSet) {
3692 Polymer.dom.flush();
3693 var newPhysicalSize = 0;
3694 var oldPhysicalSize = 0;
3695 var prevAvgCount = this._physicalAverageCount;
3696 var prevPhysicalAvg = this._physicalAverage;
3697 this._iterateItems(function(pidx, vidx) {
3698 oldPhysicalSize += this._physicalSizes[pidx] || 0;
3699 this._physicalSizes[pidx] = this._physicalItems[pidx].offsetHeight;
3700 newPhysicalSize += this._physicalSizes[pidx];
3701 this._physicalAverageCount += this._physicalSizes[pidx] ? 1 : 0;
3702 }, itemSet);
3703 this._viewportHeight = this._scrollTargetHeight;
3704 if (this.grid) {
3705 this._updateGridMetrics();
3706 this._physicalSize = Math.ceil(this._physicalCount / this._itemsPerRow) * this._rowHeight;
3707 } else {
3708 this._physicalSize = this._physicalSize + newPhysicalSize - oldPhysicalS ize;
3709 }
3710 if (this._physicalAverageCount !== prevAvgCount) {
3711 this._physicalAverage = Math.round((prevPhysicalAvg * prevAvgCount + new PhysicalSize) / this._physicalAverageCount);
3712 }
3713 },
3714 _updateGridMetrics: function() {
3715 this._viewportWidth = this.$.items.offsetWidth;
3716 this._itemWidth = this._physicalCount > 0 ? this._physicalItems[0].getBoun dingClientRect().width : DEFAULT_GRID_SIZE;
3717 this._rowHeight = this._physicalCount > 0 ? this._physicalItems[0].offsetH eight : DEFAULT_GRID_SIZE;
3718 this._itemsPerRow = this._itemWidth ? Math.floor(this._viewportWidth / thi s._itemWidth) : this._itemsPerRow;
3719 },
3720 _positionItems: function() {
3721 this._adjustScrollPosition();
3722 var y = this._physicalTop;
3723 if (this.grid) {
3724 var totalItemWidth = this._itemsPerRow * this._itemWidth;
3725 var rowOffset = (this._viewportWidth - totalItemWidth) / 2;
3726 this._iterateItems(function(pidx, vidx) {
3727 var modulus = vidx % this._itemsPerRow;
3728 var x = Math.floor(modulus * this._itemWidth + rowOffset);
3729 this.translate3d(x + 'px', y + 'px', 0, this._physicalItems[pidx]);
3730 if (this._shouldRenderNextRow(vidx)) {
3731 y += this._rowHeight;
3732 }
3733 });
3734 } else {
3735 this._iterateItems(function(pidx, vidx) {
3736 this.translate3d(0, y + 'px', 0, this._physicalItems[pidx]);
3737 y += this._physicalSizes[pidx];
3738 });
3739 }
3740 },
3741 _getPhysicalSizeIncrement: function(pidx) {
3742 if (!this.grid) {
3743 return this._physicalSizes[pidx];
3744 }
3745 if (this._computeVidx(pidx) % this._itemsPerRow !== this._itemsPerRow - 1) {
3746 return 0;
3747 }
3748 return this._rowHeight;
3749 },
3750 _shouldRenderNextRow: function(vidx) {
3751 return vidx % this._itemsPerRow === this._itemsPerRow - 1;
3752 },
3753 _adjustScrollPosition: function() {
3754 var deltaHeight = this._virtualStart === 0 ? this._physicalTop : Math.min( this._scrollPosition + this._physicalTop, 0);
3755 if (deltaHeight) {
3756 this._physicalTop = this._physicalTop - deltaHeight;
3757 if (!IOS_TOUCH_SCROLLING && this._physicalTop !== 0) {
3758 this._resetScrollPosition(this._scrollTop - deltaHeight);
3759 }
3760 }
3761 },
3762 _resetScrollPosition: function(pos) {
3763 if (this.scrollTarget) {
3764 this._scrollTop = pos;
3765 this._scrollPosition = this._scrollTop;
3766 }
3767 },
3768 _updateScrollerSize: function(forceUpdate) {
3769 if (this.grid) {
3770 this._estScrollHeight = this._virtualRowCount * this._rowHeight;
3771 } else {
3772 this._estScrollHeight = this._physicalBottom + Math.max(this._virtualCou nt - this._physicalCount - this._virtualStart, 0) * this._physicalAverage;
3773 }
3774 forceUpdate = forceUpdate || this._scrollHeight === 0;
3775 forceUpdate = forceUpdate || this._scrollPosition >= this._estScrollHeight - this._physicalSize;
3776 forceUpdate = forceUpdate || this.grid && this.$.items.style.height < this ._estScrollHeight;
3777 if (forceUpdate || Math.abs(this._estScrollHeight - this._scrollHeight) >= this._optPhysicalSize) {
3778 this.$.items.style.height = this._estScrollHeight + 'px';
3779 this._scrollHeight = this._estScrollHeight;
3780 }
3781 },
3782 scrollToItem: function(item) {
3783 return this.scrollToIndex(this.items.indexOf(item));
3784 },
3785 scrollToIndex: function(idx) {
3786 if (typeof idx !== 'number' || idx < 0 || idx > this.items.length - 1) {
3787 return;
3788 }
3789 Polymer.dom.flush();
3790 if (this._physicalCount === 0) {
3791 return;
3792 }
3793 idx = Math.min(Math.max(idx, 0), this._virtualCount - 1);
3794 if (!this._isIndexRendered(idx) || idx >= this._maxVirtualStart) {
3795 this._virtualStart = this.grid ? idx - this._itemsPerRow * 2 : idx - 1;
3796 }
3797 this._manageFocus();
3798 this._assignModels();
3799 this._updateMetrics();
3800 this._physicalTop = Math.floor(this._virtualStart / this._itemsPerRow) * t his._physicalAverage;
3801 var currentTopItem = this._physicalStart;
3802 var currentVirtualItem = this._virtualStart;
3803 var targetOffsetTop = 0;
3804 var hiddenContentSize = this._hiddenContentSize;
3805 while (currentVirtualItem < idx && targetOffsetTop <= hiddenContentSize) {
3806 targetOffsetTop = targetOffsetTop + this._getPhysicalSizeIncrement(curre ntTopItem);
3807 currentTopItem = (currentTopItem + 1) % this._physicalCount;
3808 currentVirtualItem++;
3809 }
3810 this._updateScrollerSize(true);
3811 this._positionItems();
3812 this._resetScrollPosition(this._physicalTop + this._scrollerPaddingTop + t argetOffsetTop);
3813 this._increasePoolIfNeeded();
3814 this._firstVisibleIndexVal = null;
3815 this._lastVisibleIndexVal = null;
3816 },
3817 _resetAverage: function() {
3818 this._physicalAverage = 0;
3819 this._physicalAverageCount = 0;
3820 },
3821 _resizeHandler: function() {
3822 if (IOS && Math.abs(this._viewportHeight - this._scrollTargetHeight) < 100 ) {
3823 return;
3824 }
3825 Polymer.dom.addDebouncer(this.debounce('_debounceTemplate', function() {
3826 this.updateViewportBoundaries();
3827 this._render();
3828 if (this._physicalCount > 0 && this._isVisible) {
3829 this._resetAverage();
3830 this.scrollToIndex(this.firstVisibleIndex);
3831 }
3832 }.bind(this), 1));
3833 },
3834 _getModelFromItem: function(item) {
3835 var key = this._collection.getKey(item);
3836 var pidx = this._physicalIndexForKey[key];
3837 if (pidx != null) {
3838 return this._physicalItems[pidx]._templateInstance;
3839 }
3840 return null;
3841 },
3842 _getNormalizedItem: function(item) {
3843 if (this._collection.getKey(item) === undefined) {
3844 if (typeof item === 'number') {
3845 item = this.items[item];
3846 if (!item) {
3847 throw new RangeError('<item> not found');
3848 }
3849 return item;
3850 }
3851 throw new TypeError('<item> should be a valid item');
3852 }
3853 return item;
3854 },
3855 selectItem: function(item) {
3856 item = this._getNormalizedItem(item);
3857 var model = this._getModelFromItem(item);
3858 if (!this.multiSelection && this.selectedItem) {
3859 this.deselectItem(this.selectedItem);
3860 }
3861 if (model) {
3862 model[this.selectedAs] = true;
3863 }
3864 this.$.selector.select(item);
3865 this.updateSizeForItem(item);
3866 },
3867 deselectItem: function(item) {
3868 item = this._getNormalizedItem(item);
3869 var model = this._getModelFromItem(item);
3870 if (model) {
3871 model[this.selectedAs] = false;
3872 }
3873 this.$.selector.deselect(item);
3874 this.updateSizeForItem(item);
3875 },
3876 toggleSelectionForItem: function(item) {
3877 item = this._getNormalizedItem(item);
3878 if (this.$.selector.isSelected(item)) {
3879 this.deselectItem(item);
3880 } else {
3881 this.selectItem(item);
3882 }
3883 },
3884 clearSelection: function() {
3885 function unselect(item) {
3886 var model = this._getModelFromItem(item);
3887 if (model) {
3888 model[this.selectedAs] = false;
3889 }
3890 }
3891 if (Array.isArray(this.selectedItems)) {
3892 this.selectedItems.forEach(unselect, this);
3893 } else if (this.selectedItem) {
3894 unselect.call(this, this.selectedItem);
3895 }
3896 this.$.selector.clearSelection();
3897 },
3898 _selectionEnabledChanged: function(selectionEnabled) {
3899 var handler = selectionEnabled ? this.listen : this.unlisten;
3900 handler.call(this, this, 'tap', '_selectionHandler');
3901 },
3902 _selectionHandler: function(e) {
3903 var model = this.modelForElement(e.target);
3904 if (!model) {
3905 return;
3906 }
3907 var modelTabIndex, activeElTabIndex;
3908 var target = Polymer.dom(e).path[0];
3909 var activeEl = Polymer.dom(this.domHost ? this.domHost.root : document).ac tiveElement;
3910 var physicalItem = this._physicalItems[this._getPhysicalIndex(model[this.i ndexAs])];
3911 if (target.localName === 'input' || target.localName === 'button' || targe t.localName === 'select') {
3912 return;
3913 }
3914 modelTabIndex = model.tabIndex;
3915 model.tabIndex = SECRET_TABINDEX;
3916 activeElTabIndex = activeEl ? activeEl.tabIndex : -1;
3917 model.tabIndex = modelTabIndex;
3918 if (activeEl && physicalItem !== activeEl && physicalItem.contains(activeE l) && activeElTabIndex !== SECRET_TABINDEX) {
3919 return;
3920 }
3921 this.toggleSelectionForItem(model[this.as]);
3922 },
3923 _multiSelectionChanged: function(multiSelection) {
3924 this.clearSelection();
3925 this.$.selector.multi = multiSelection;
3926 },
3927 updateSizeForItem: function(item) {
3928 item = this._getNormalizedItem(item);
3929 var key = this._collection.getKey(item);
3930 var pidx = this._physicalIndexForKey[key];
3931 if (pidx != null) {
3932 this._updateMetrics([ pidx ]);
3933 this._positionItems();
3934 }
3935 },
3936 _manageFocus: function() {
3937 var fidx = this._focusedIndex;
3938 if (fidx >= 0 && fidx < this._virtualCount) {
3939 if (this._isIndexRendered(fidx)) {
3940 this._restoreFocusedItem();
3941 } else {
3942 this._createFocusBackfillItem();
3943 }
3944 } else if (this._virtualCount > 0 && this._physicalCount > 0) {
3945 this._focusedIndex = this._virtualStart;
3946 this._focusedItem = this._physicalItems[this._physicalStart];
3947 }
3948 },
3949 _isIndexRendered: function(idx) {
3950 return idx >= this._virtualStart && idx <= this._virtualEnd;
3951 },
3952 _isIndexVisible: function(idx) {
3953 return idx >= this.firstVisibleIndex && idx <= this.lastVisibleIndex;
3954 },
3955 _getPhysicalIndex: function(idx) {
3956 return this._physicalIndexForKey[this._collection.getKey(this._getNormaliz edItem(idx))];
3957 },
3958 _focusPhysicalItem: function(idx) {
3959 if (idx < 0 || idx >= this._virtualCount) {
3960 return;
3961 }
3962 this._restoreFocusedItem();
3963 if (!this._isIndexRendered(idx)) {
3964 this.scrollToIndex(idx);
3965 }
3966 var physicalItem = this._physicalItems[this._getPhysicalIndex(idx)];
3967 var model = physicalItem._templateInstance;
3968 var focusable;
3969 model.tabIndex = SECRET_TABINDEX;
3970 if (physicalItem.tabIndex === SECRET_TABINDEX) {
3971 focusable = physicalItem;
3972 }
3973 if (!focusable) {
3974 focusable = Polymer.dom(physicalItem).querySelector('[tabindex="' + SECR ET_TABINDEX + '"]');
3975 }
3976 model.tabIndex = 0;
3977 this._focusedIndex = idx;
3978 focusable && focusable.focus();
3979 },
3980 _removeFocusedItem: function() {
3981 if (this._offscreenFocusedItem) {
3982 Polymer.dom(this).removeChild(this._offscreenFocusedItem);
3983 }
3984 this._offscreenFocusedItem = null;
3985 this._focusBackfillItem = null;
3986 this._focusedItem = null;
3987 this._focusedIndex = -1;
3988 },
3989 _createFocusBackfillItem: function() {
3990 var pidx, fidx = this._focusedIndex;
3991 if (this._offscreenFocusedItem || fidx < 0) {
3992 return;
3993 }
3994 if (!this._focusBackfillItem) {
3995 var stampedTemplate = this.stamp(null);
3996 this._focusBackfillItem = stampedTemplate.root.querySelector('*');
3997 Polymer.dom(this).appendChild(stampedTemplate.root);
3998 }
3999 pidx = this._getPhysicalIndex(fidx);
4000 if (pidx != null) {
4001 this._offscreenFocusedItem = this._physicalItems[pidx];
4002 this._physicalItems[pidx] = this._focusBackfillItem;
4003 this.translate3d(0, HIDDEN_Y, 0, this._offscreenFocusedItem);
4004 }
4005 },
4006 _restoreFocusedItem: function() {
4007 var pidx, fidx = this._focusedIndex;
4008 if (!this._offscreenFocusedItem || this._focusedIndex < 0) {
4009 return;
4010 }
4011 this._assignModels();
4012 pidx = this._getPhysicalIndex(fidx);
4013 if (pidx != null) {
4014 this._focusBackfillItem = this._physicalItems[pidx];
4015 this._physicalItems[pidx] = this._offscreenFocusedItem;
4016 this._offscreenFocusedItem = null;
4017 this.translate3d(0, HIDDEN_Y, 0, this._focusBackfillItem);
4018 }
4019 },
4020 _didFocus: function(e) {
4021 var targetModel = this.modelForElement(e.target);
4022 var focusedModel = this._focusedItem ? this._focusedItem._templateInstance : null;
4023 var hasOffscreenFocusedItem = this._offscreenFocusedItem !== null;
4024 var fidx = this._focusedIndex;
4025 if (!targetModel || !focusedModel) {
4026 return;
4027 }
4028 if (focusedModel === targetModel) {
4029 if (!this._isIndexVisible(fidx)) {
4030 this.scrollToIndex(fidx);
4031 }
4032 } else {
4033 this._restoreFocusedItem();
4034 focusedModel.tabIndex = -1;
4035 targetModel.tabIndex = 0;
4036 fidx = targetModel[this.indexAs];
4037 this._focusedIndex = fidx;
4038 this._focusedItem = this._physicalItems[this._getPhysicalIndex(fidx)];
4039 if (hasOffscreenFocusedItem && !this._offscreenFocusedItem) {
4040 this._update();
4041 }
4042 }
4043 },
4044 _didMoveUp: function() {
4045 this._focusPhysicalItem(this._focusedIndex - 1);
4046 },
4047 _didMoveDown: function(e) {
4048 e.detail.keyboardEvent.preventDefault();
4049 this._focusPhysicalItem(this._focusedIndex + 1);
4050 },
4051 _didEnter: function(e) {
4052 this._focusPhysicalItem(this._focusedIndex);
4053 this._selectionHandler(e.detail.keyboardEvent);
4054 }
4055 });
4056 })();
4057
4058 Polymer({
4059 is: 'iron-scroll-threshold',
4060 properties: {
4061 upperThreshold: {
4062 type: Number,
4063 value: 100
4064 },
4065 lowerThreshold: {
4066 type: Number,
4067 value: 100
4068 },
4069 upperTriggered: {
4070 type: Boolean,
4071 value: false,
4072 notify: true,
4073 readOnly: true
4074 },
4075 lowerTriggered: {
4076 type: Boolean,
4077 value: false,
4078 notify: true,
4079 readOnly: true
4080 },
4081 horizontal: {
4082 type: Boolean,
4083 value: false
4084 }
4085 },
4086 behaviors: [ Polymer.IronScrollTargetBehavior ],
4087 observers: [ '_setOverflow(scrollTarget)', '_initCheck(horizontal, isAttached) ' ],
4088 get _defaultScrollTarget() {
4089 return this;
4090 },
4091 _setOverflow: function(scrollTarget) {
4092 this.style.overflow = scrollTarget === this ? 'auto' : '';
4093 },
4094 _scrollHandler: function() {
4095 var THROTTLE_THRESHOLD = 200;
4096 if (!this.isDebouncerActive('_checkTheshold')) {
4097 this.debounce('_checkTheshold', function() {
4098 this.checkScrollThesholds();
4099 }, THROTTLE_THRESHOLD);
4100 }
4101 },
4102 _initCheck: function(horizontal, isAttached) {
4103 if (isAttached) {
4104 this.debounce('_init', function() {
4105 this.clearTriggers();
4106 this.checkScrollThesholds();
4107 });
4108 }
4109 },
4110 checkScrollThesholds: function() {
4111 if (!this.scrollTarget || this.lowerTriggered && this.upperTriggered) {
4112 return;
4113 }
4114 var upperScrollValue = this.horizontal ? this._scrollLeft : this._scrollTop;
4115 var lowerScrollValue = this.horizontal ? this.scrollTarget.scrollWidth - thi s._scrollTargetWidth - this._scrollLeft : this.scrollTarget.scrollHeight - this. _scrollTargetHeight - this._scrollTop;
4116 if (upperScrollValue <= this.upperThreshold && !this.upperTriggered) {
4117 this._setUpperTriggered(true);
4118 this.fire('upper-threshold');
4119 }
4120 if (lowerScrollValue <= this.lowerThreshold && !this.lowerTriggered) {
4121 this._setLowerTriggered(true);
4122 this.fire('lower-threshold');
4123 }
4124 },
4125 clearTriggers: function() {
4126 this._setUpperTriggered(false);
4127 this._setLowerTriggered(false);
4128 }
4129 });
4130
4131 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 43 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
4132 // Use of this source code is governed by a BSD-style license that can be 44 // Use of this source code is governed by a BSD-style license that can be
4133 // found in the LICENSE file. 45 // found in the LICENSE file.
4134 var EventTrackerEntry; 46 var EventTrackerEntry;function EventTracker(){this.listeners_=[]}EventTracker.pr ototype={add:function(target,eventType,listener,opt_capture){var capture=!!opt_c apture;var h={target:target,eventType:eventType,listener:listener,capture:captur e};this.listeners_.push(h);target.addEventListener(eventType,listener,capture)}, remove:function(target,eventType){this.listeners_=this.listeners_.filter(functio n(h){if(h.target==target&&(!eventType||h.eventType==eventType)){EventTracker.rem oveEventListener_(h);return false}return true})},removeAll:function(){this.liste ners_.forEach(EventTracker.removeEventListener_);this.listeners_=[]}};EventTrack er.removeEventListener_=function(h){h.target.removeEventListener(h.eventType,h.l istener,h.capture)};
4135
4136 function EventTracker() {
4137 this.listeners_ = [];
4138 }
4139
4140 EventTracker.prototype = {
4141 add: function(target, eventType, listener, opt_capture) {
4142 var capture = !!opt_capture;
4143 var h = {
4144 target: target,
4145 eventType: eventType,
4146 listener: listener,
4147 capture: capture
4148 };
4149 this.listeners_.push(h);
4150 target.addEventListener(eventType, listener, capture);
4151 },
4152 remove: function(target, eventType) {
4153 this.listeners_ = this.listeners_.filter(function(h) {
4154 if (h.target == target && (!eventType || h.eventType == eventType)) {
4155 EventTracker.removeEventListener_(h);
4156 return false;
4157 }
4158 return true;
4159 });
4160 },
4161 removeAll: function() {
4162 this.listeners_.forEach(EventTracker.removeEventListener_);
4163 this.listeners_ = [];
4164 }
4165 };
4166
4167 EventTracker.removeEventListener_ = function(h) {
4168 h.target.removeEventListener(h.eventType, h.listener, h.capture);
4169 };
4170
4171 // Copyright 2014 The Chromium Authors. All rights reserved. 47 // Copyright 2014 The Chromium Authors. All rights reserved.
4172 // Use of this source code is governed by a BSD-style license that can be 48 // Use of this source code is governed by a BSD-style license that can be
4173 // found in the LICENSE file. 49 // found in the LICENSE file.
4174 cr.define('cr.ui', function() { 50 cr.define("cr.ui",function(){function FocusRow(root,boundary,opt_delegate){this. root=root;this.boundary_=boundary||document.documentElement;this.delegate=opt_de legate;this.eventTracker=new EventTracker}FocusRow.Delegate=function(){};FocusRo w.Delegate.prototype={onKeydown:assertNotReached,onFocus:assertNotReached};Focus Row.ACTIVE_CLASS="focus-row-active";FocusRow.isFocusable=function(element){if(!e lement||element.disabled)return false;function isVisible(element){assertInstance of(element,Element);var style=window.getComputedStyle(element);if(style.visibili ty=="hidden"||style.display=="none")return false;var parent=element.parentNode;i f(!parent)return false;if(parent==element.ownerDocument||parent instanceof Docum entFragment)return true;return isVisible(parent)}return isVisible(element)};Focu sRow.prototype={addItem:function(type,query){assert(type);var element=this.root. querySelector(query);if(!element)return false;element.setAttribute("focus-type", type);element.tabIndex=this.isActive()?0:-1;this.eventTracker.add(element,"blur" ,this.onBlur_.bind(this));this.eventTracker.add(element,"focus",this.onFocus_.bi nd(this));this.eventTracker.add(element,"keydown",this.onKeydown_.bind(this));th is.eventTracker.add(element,"mousedown",this.onMousedown_.bind(this));return tru e},destroy:function(){this.eventTracker.removeAll()},getCustomEquivalent:functio n(sampleElement){return assert(this.getFirstFocusable())},getElements:function() {var elements=this.root.querySelectorAll("[focus-type]");return Array.prototype. slice.call(elements)},getEquivalentElement:function(sampleElement){if(this.getFo cusableElements().indexOf(sampleElement)>=0)return sampleElement;var sampleFocus Type=this.getTypeForElement(sampleElement);if(sampleFocusType){var sameType=this .getFirstFocusable(sampleFocusType);if(sameType)return sameType}return this.getC ustomEquivalent(sampleElement)},getFirstFocusable:function(opt_type){var filter= opt_type?'="'+opt_type+'"':"";var elements=this.root.querySelectorAll("[focus-ty pe"+filter+"]");for(var i=0;i<elements.length;++i){if(cr.ui.FocusRow.isFocusable (elements[i]))return elements[i]}return null},getFocusableElements:function(){re turn this.getElements().filter(cr.ui.FocusRow.isFocusable)},getTypeForElement:fu nction(element){return element.getAttribute("focus-type")||""},isActive:function (){return this.root.classList.contains(FocusRow.ACTIVE_CLASS)},makeActive:functi on(active){if(active==this.isActive())return;this.getElements().forEach(function (element){element.tabIndex=active?0:-1});this.root.classList.toggle(FocusRow.ACT IVE_CLASS,active)},onBlur_:function(e){if(!this.boundary_.contains(e.relatedTarg et))return;var currentTarget=e.currentTarget;if(this.getFocusableElements().inde xOf(currentTarget)>=0)this.makeActive(false)},onFocus_:function(e){if(this.deleg ate)this.delegate.onFocus(this,e)},onMousedown_:function(e){if(e.button)return;i f(!e.currentTarget.disabled)e.currentTarget.tabIndex=0},onKeydown_:function(e){v ar elements=this.getFocusableElements();var currentElement=e.currentTarget;var e lementIndex=elements.indexOf(currentElement);assert(elementIndex>=0);if(this.del egate&&this.delegate.onKeydown(this,e))return;if(e.altKey||e.ctrlKey||e.metaKey| |e.shiftKey)return;var index=-1;if(e.key=="ArrowLeft")index=elementIndex+(isRTL( )?1:-1);else if(e.key=="ArrowRight")index=elementIndex+(isRTL()?-1:1);else if(e. key=="Home")index=0;else if(e.key=="End")index=elements.length-1;var elementToFo cus=elements[index];if(elementToFocus){this.getEquivalentElement(elementToFocus) .focus();e.preventDefault()}}};return{FocusRow:FocusRow}});
4175 function FocusRow(root, boundary, opt_delegate) {
4176 this.root = root;
4177 this.boundary_ = boundary || document.documentElement;
4178 this.delegate = opt_delegate;
4179 this.eventTracker = new EventTracker();
4180 }
4181 FocusRow.Delegate = function() {};
4182 FocusRow.Delegate.prototype = {
4183 onKeydown: assertNotReached,
4184 onFocus: assertNotReached
4185 };
4186 FocusRow.ACTIVE_CLASS = 'focus-row-active';
4187 FocusRow.isFocusable = function(element) {
4188 if (!element || element.disabled) return false;
4189 function isVisible(element) {
4190 assertInstanceof(element, Element);
4191 var style = window.getComputedStyle(element);
4192 if (style.visibility == 'hidden' || style.display == 'none') return false;
4193 var parent = element.parentNode;
4194 if (!parent) return false;
4195 if (parent == element.ownerDocument || parent instanceof DocumentFragment) return true;
4196 return isVisible(parent);
4197 }
4198 return isVisible(element);
4199 };
4200 FocusRow.prototype = {
4201 addItem: function(type, query) {
4202 assert(type);
4203 var element = this.root.querySelector(query);
4204 if (!element) return false;
4205 element.setAttribute('focus-type', type);
4206 element.tabIndex = this.isActive() ? 0 : -1;
4207 this.eventTracker.add(element, 'blur', this.onBlur_.bind(this));
4208 this.eventTracker.add(element, 'focus', this.onFocus_.bind(this));
4209 this.eventTracker.add(element, 'keydown', this.onKeydown_.bind(this));
4210 this.eventTracker.add(element, 'mousedown', this.onMousedown_.bind(this));
4211 return true;
4212 },
4213 destroy: function() {
4214 this.eventTracker.removeAll();
4215 },
4216 getCustomEquivalent: function(sampleElement) {
4217 return assert(this.getFirstFocusable());
4218 },
4219 getElements: function() {
4220 var elements = this.root.querySelectorAll('[focus-type]');
4221 return Array.prototype.slice.call(elements);
4222 },
4223 getEquivalentElement: function(sampleElement) {
4224 if (this.getFocusableElements().indexOf(sampleElement) >= 0) return sample Element;
4225 var sampleFocusType = this.getTypeForElement(sampleElement);
4226 if (sampleFocusType) {
4227 var sameType = this.getFirstFocusable(sampleFocusType);
4228 if (sameType) return sameType;
4229 }
4230 return this.getCustomEquivalent(sampleElement);
4231 },
4232 getFirstFocusable: function(opt_type) {
4233 var filter = opt_type ? '="' + opt_type + '"' : '';
4234 var elements = this.root.querySelectorAll('[focus-type' + filter + ']');
4235 for (var i = 0; i < elements.length; ++i) {
4236 if (cr.ui.FocusRow.isFocusable(elements[i])) return elements[i];
4237 }
4238 return null;
4239 },
4240 getFocusableElements: function() {
4241 return this.getElements().filter(cr.ui.FocusRow.isFocusable);
4242 },
4243 getTypeForElement: function(element) {
4244 return element.getAttribute('focus-type') || '';
4245 },
4246 isActive: function() {
4247 return this.root.classList.contains(FocusRow.ACTIVE_CLASS);
4248 },
4249 makeActive: function(active) {
4250 if (active == this.isActive()) return;
4251 this.getElements().forEach(function(element) {
4252 element.tabIndex = active ? 0 : -1;
4253 });
4254 this.root.classList.toggle(FocusRow.ACTIVE_CLASS, active);
4255 },
4256 onBlur_: function(e) {
4257 if (!this.boundary_.contains(e.relatedTarget)) return;
4258 var currentTarget = e.currentTarget;
4259 if (this.getFocusableElements().indexOf(currentTarget) >= 0) this.makeActi ve(false);
4260 },
4261 onFocus_: function(e) {
4262 if (this.delegate) this.delegate.onFocus(this, e);
4263 },
4264 onMousedown_: function(e) {
4265 if (e.button) return;
4266 if (!e.currentTarget.disabled) e.currentTarget.tabIndex = 0;
4267 },
4268 onKeydown_: function(e) {
4269 var elements = this.getFocusableElements();
4270 var currentElement = e.currentTarget;
4271 var elementIndex = elements.indexOf(currentElement);
4272 assert(elementIndex >= 0);
4273 if (this.delegate && this.delegate.onKeydown(this, e)) return;
4274 if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) return;
4275 var index = -1;
4276 if (e.key == 'ArrowLeft') index = elementIndex + (isRTL() ? 1 : -1); else if (e.key == 'ArrowRight') index = elementIndex + (isRTL() ? -1 : 1); else if (e .key == 'Home') index = 0; else if (e.key == 'End') index = elements.length - 1;
4277 var elementToFocus = elements[index];
4278 if (elementToFocus) {
4279 this.getEquivalentElement(elementToFocus).focus();
4280 e.preventDefault();
4281 }
4282 }
4283 };
4284 return {
4285 FocusRow: FocusRow
4286 };
4287 });
4288
4289 // Copyright 2016 The Chromium Authors. All rights reserved. 51 // Copyright 2016 The Chromium Authors. All rights reserved.
4290 // Use of this source code is governed by a BSD-style license that can be 52 // Use of this source code is governed by a BSD-style license that can be
4291 // found in the LICENSE file. 53 // found in the LICENSE file.
4292 cr.define('cr.icon', function() { 54 cr.define("cr.icon",function(){function getSupportedScaleFactors(){var supported ScaleFactors=[];if(!cr.isIOS){supportedScaleFactors.push(1)}if(cr.isMac||cr.isCh romeOS||cr.isWindows||cr.isLinux){supportedScaleFactors.push(2)}else{supportedSc aleFactors.push(window.devicePixelRatio)}return supportedScaleFactors}function g etImageSet(path){var supportedScaleFactors=getSupportedScaleFactors();var replac eStartIndex=path.indexOf("scalefactor");if(replaceStartIndex<0)return url(path); var s="";for(var i=0;i<supportedScaleFactors.length;++i){var scaleFactor=support edScaleFactors[i];var pathWithScaleFactor=path.substr(0,replaceStartIndex)+scale Factor+path.substr(replaceStartIndex+"scalefactor".length);s+=url(pathWithScaleF actor)+" "+scaleFactor+"x";if(i!=supportedScaleFactors.length-1)s+=", "}return"- webkit-image-set("+s+")"}function getImage(path){var chromeThemePath="chrome://t heme";var isChromeThemeUrl=path.slice(0,chromeThemePath.length)==chromeThemePath ;return isChromeThemeUrl?getImageSet(path+"@scalefactorx"):url(path)}var FAVICON _URL_REGEX=/\.ico$/i;function getFavicon(url,opt_size,opt_type){var size=opt_siz e||16;var type=opt_type||"favicon";return getImageSet("chrome://"+type+"/size/"+ size+"@scalefactorx/"+(FAVICON_URL_REGEX.test(url)?"iconurl/":"")+url)}return{ge tImage:getImage,getFavicon:getFavicon}});
4293 function getSupportedScaleFactors() {
4294 var supportedScaleFactors = [];
4295 if (!cr.isIOS) {
4296 supportedScaleFactors.push(1);
4297 }
4298 if (cr.isMac || cr.isChromeOS || cr.isWindows || cr.isLinux) {
4299 supportedScaleFactors.push(2);
4300 } else {
4301 supportedScaleFactors.push(window.devicePixelRatio);
4302 }
4303 return supportedScaleFactors;
4304 }
4305 function getImageSet(path) {
4306 var supportedScaleFactors = getSupportedScaleFactors();
4307 var replaceStartIndex = path.indexOf('scalefactor');
4308 if (replaceStartIndex < 0) return url(path);
4309 var s = '';
4310 for (var i = 0; i < supportedScaleFactors.length; ++i) {
4311 var scaleFactor = supportedScaleFactors[i];
4312 var pathWithScaleFactor = path.substr(0, replaceStartIndex) + scaleFactor + path.substr(replaceStartIndex + 'scalefactor'.length);
4313 s += url(pathWithScaleFactor) + ' ' + scaleFactor + 'x';
4314 if (i != supportedScaleFactors.length - 1) s += ', ';
4315 }
4316 return '-webkit-image-set(' + s + ')';
4317 }
4318 function getImage(path) {
4319 var chromeThemePath = 'chrome://theme';
4320 var isChromeThemeUrl = path.slice(0, chromeThemePath.length) == chromeThemeP ath;
4321 return isChromeThemeUrl ? getImageSet(path + '@scalefactorx') : url(path);
4322 }
4323 var FAVICON_URL_REGEX = /\.ico$/i;
4324 function getFavicon(url, opt_size, opt_type) {
4325 var size = opt_size || 16;
4326 var type = opt_type || 'favicon';
4327 return getImageSet('chrome://' + type + '/size/' + size + '@scalefactorx/' + (FAVICON_URL_REGEX.test(url) ? 'iconurl/' : '') + url);
4328 }
4329 return {
4330 getImage: getImage,
4331 getFavicon: getFavicon
4332 };
4333 });
4334
4335 // Copyright 2016 The Chromium Authors. All rights reserved. 55 // Copyright 2016 The Chromium Authors. All rights reserved.
4336 // Use of this source code is governed by a BSD-style license that can be 56 // Use of this source code is governed by a BSD-style license that can be
4337 // found in the LICENSE file. 57 // found in the LICENSE file.
4338 Polymer({ 58 Polymer({is:"history-searched-label",properties:{title:String,searchTerm:String} ,observers:["setSearchedTextToBold_(title, searchTerm)"],setSearchedTextToBold_: function(){var i=0;var titleText=this.title;if(this.searchTerm==""||this.searchT erm==null){this.textContent=titleText;return}var re=new RegExp(quoteString(this. searchTerm),"gim");var match;this.textContent="";while(match=re.exec(titleText)) {if(match.index>i)this.appendChild(document.createTextNode(titleText.slice(i,mat ch.index)));i=re.lastIndex;var b=document.createElement("b");b.textContent=title Text.substring(match.index,i);this.appendChild(b)}if(i<titleText.length)this.app endChild(document.createTextNode(titleText.slice(i)))}});
4339 is: 'history-searched-label',
4340 properties: {
4341 title: String,
4342 searchTerm: String
4343 },
4344 observers: [ 'setSearchedTextToBold_(title, searchTerm)' ],
4345 setSearchedTextToBold_: function() {
4346 var i = 0;
4347 var titleText = this.title;
4348 if (this.searchTerm == '' || this.searchTerm == null) {
4349 this.textContent = titleText;
4350 return;
4351 }
4352 var re = new RegExp(quoteString(this.searchTerm), 'gim');
4353 var match;
4354 this.textContent = '';
4355 while (match = re.exec(titleText)) {
4356 if (match.index > i) this.appendChild(document.createTextNode(titleText.sl ice(i, match.index)));
4357 i = re.lastIndex;
4358 var b = document.createElement('b');
4359 b.textContent = titleText.substring(match.index, i);
4360 this.appendChild(b);
4361 }
4362 if (i < titleText.length) this.appendChild(document.createTextNode(titleText .slice(i)));
4363 }
4364 });
4365
4366 // Copyright 2015 The Chromium Authors. All rights reserved. 59 // Copyright 2015 The Chromium Authors. All rights reserved.
4367 // Use of this source code is governed by a BSD-style license that can be 60 // Use of this source code is governed by a BSD-style license that can be
4368 // found in the LICENSE file. 61 // found in the LICENSE file.
4369 function HistoryFocusRow(root, boundary, delegate) { 62 function HistoryFocusRow(root,boundary,delegate){cr.ui.FocusRow.call(this,root,b oundary,delegate);this.addItems()}HistoryFocusRow.prototype={__proto__:cr.ui.Foc usRow.prototype,getCustomEquivalent:function(sampleElement){var equivalent;if(th is.getTypeForElement(sampleElement)=="star")equivalent=this.getFirstFocusable("t itle");return equivalent||cr.ui.FocusRow.prototype.getCustomEquivalent.call(this ,sampleElement)},addItems:function(){this.destroy();assert(this.addItem("checkbo x","#checkbox"));assert(this.addItem("title","#title"));assert(this.addItem("men u-button","#menu-button"));this.addItem("star","#bookmark-star")}};cr.define("md _history",function(){function FocusRowDelegate(historyItemElement){this.historyI temElement=historyItemElement}FocusRowDelegate.prototype={onFocus:function(row,e ){this.historyItemElement.lastFocused=e.path[0]},onKeydown:function(row,e){if(e. key=="Enter")e.stopPropagation();return false}};var HistoryItem=Polymer({is:"his tory-item",properties:{item:{type:Object,observer:"showIcon_"},searchTerm:{type: String},selected:{type:Boolean,reflectToAttribute:true},isCardStart:{type:Boolea n,reflectToAttribute:true},isCardEnd:{type:Boolean,reflectToAttribute:true},embe dded:{type:Boolean,reflectToAttribute:true},hasTimeGap:{type:Boolean},numberOfIt ems:{type:Number},path:String,index:Number,lastFocused:{type:Object,notify:true} ,ironListTabIndex:{type:Number,observer:"ironListTabIndexChanged_"}},row_:null,a ttached:function(){Polymer.RenderStatus.afterNextRender(this,function(){this.row _=new HistoryFocusRow(this.$["sizing-container"],null,new FocusRowDelegate(this) );this.row_.makeActive(this.ironListTabIndex==0);this.listen(this,"focus","onFoc us_");this.listen(this,"dom-change","onDomChange_")})},detached:function(){this. unlisten(this,"focus","onFocus_");this.unlisten(this,"dom-change","onDomChange_" );if(this.row_)this.row_.destroy()},onFocus_:function(){if(this.lastFocused)this .row_.getEquivalentElement(this.lastFocused).focus();else this.row_.getFirstFocu sable().focus();this.tabIndex=-1},ironListTabIndexChanged_:function(){if(this.ro w_)this.row_.makeActive(this.ironListTabIndex==0)},onDomChange_:function(){if(th is.row_)this.row_.addItems()},onCheckboxSelected_:function(e){this.fire("history -checkbox-select",{element:this,shiftKey:e.shiftKey});e.preventDefault()},onChec kboxMousedown_:function(e){if(e.shiftKey)e.preventDefault()},getEntrySummary_:fu nction(){var item=this.item;return loadTimeData.getStringF("entrySummary",item.d ateTimeOfDay,item.starred?loadTimeData.getString("bookmarked"):"",item.title,ite m.domain)},getAriaChecked_:function(selected){return selected?"true":"false"},on RemoveBookmarkTap_:function(){if(!this.item.starred)return;if(this.$$("#bookmark -star")==this.root.activeElement)this.$["menu-button"].focus();var browserServic e=md_history.BrowserService.getInstance();browserService.removeBookmark(this.ite m.url);browserService.recordAction("BookmarkStarClicked");this.fire("remove-book mark-stars",this.item.url)},onMenuButtonTap_:function(e){this.fire("toggle-menu" ,{target:Polymer.dom(e).localTarget,index:this.index,item:this.item,path:this.pa th});e.stopPropagation()},onLinkClick_:function(){var browserService=md_history. BrowserService.getInstance();browserService.recordAction("EntryLinkClick");if(th is.searchTerm)browserService.recordAction("SearchResultClick");if(this.index==un defined)return;browserService.recordHistogram("HistoryPage.ClickPosition",this.i ndex,UMA_MAX_BUCKET_VALUE);if(this.index<=UMA_MAX_SUBSET_BUCKET_VALUE){browserSe rvice.recordHistogram("HistoryPage.ClickPositionSubset",this.index,UMA_MAX_SUBSE T_BUCKET_VALUE)}},onLinkRightClick_:function(){md_history.BrowserService.getInst ance().recordAction("EntryLinkRightClick")},showIcon_:function(){this.$.icon.sty le.backgroundImage=cr.icon.getFavicon(this.item.url)},selectionNotAllowed_:funct ion(){return!loadTimeData.getBoolean("allowDeletingHistory")},cardTitle_:functio n(numberOfItems,historyDate,search){if(!search)return this.item.dateRelativeDay; var resultId=numberOfItems==1?"searchResult":"searchResults";return loadTimeData .getStringF("foundSearchResults",numberOfItems,loadTimeData.getString(resultId), search)}});HistoryItem.needsTimeGap=function(visits,currentIndex,searchedTerm){i f(currentIndex>=visits.length-1||visits.length==0)return false;var currentItem=v isits[currentIndex];var nextItem=visits[currentIndex+1];if(searchedTerm)return c urrentItem.dateShort!=nextItem.dateShort;return currentItem.time-nextItem.time>B ROWSING_GAP_TIME&&currentItem.dateRelativeDay==nextItem.dateRelativeDay};return{ HistoryItem:HistoryItem}});
4370 cr.ui.FocusRow.call(this, root, boundary, delegate);
4371 this.addItems();
4372 }
4373
4374 HistoryFocusRow.prototype = {
4375 __proto__: cr.ui.FocusRow.prototype,
4376 getCustomEquivalent: function(sampleElement) {
4377 var equivalent;
4378 if (this.getTypeForElement(sampleElement) == 'star') equivalent = this.getFi rstFocusable('title');
4379 return equivalent || cr.ui.FocusRow.prototype.getCustomEquivalent.call(this, sampleElement);
4380 },
4381 addItems: function() {
4382 this.destroy();
4383 assert(this.addItem('checkbox', '#checkbox'));
4384 assert(this.addItem('title', '#title'));
4385 assert(this.addItem('menu-button', '#menu-button'));
4386 this.addItem('star', '#bookmark-star');
4387 }
4388 };
4389
4390 cr.define('md_history', function() {
4391 function FocusRowDelegate(historyItemElement) {
4392 this.historyItemElement = historyItemElement;
4393 }
4394 FocusRowDelegate.prototype = {
4395 onFocus: function(row, e) {
4396 this.historyItemElement.lastFocused = e.path[0];
4397 },
4398 onKeydown: function(row, e) {
4399 if (e.key == 'Enter') e.stopPropagation();
4400 return false;
4401 }
4402 };
4403 var HistoryItem = Polymer({
4404 is: 'history-item',
4405 properties: {
4406 item: {
4407 type: Object,
4408 observer: 'showIcon_'
4409 },
4410 searchTerm: {
4411 type: String
4412 },
4413 selected: {
4414 type: Boolean,
4415 reflectToAttribute: true
4416 },
4417 isCardStart: {
4418 type: Boolean,
4419 reflectToAttribute: true
4420 },
4421 isCardEnd: {
4422 type: Boolean,
4423 reflectToAttribute: true
4424 },
4425 embedded: {
4426 type: Boolean,
4427 reflectToAttribute: true
4428 },
4429 hasTimeGap: {
4430 type: Boolean
4431 },
4432 numberOfItems: {
4433 type: Number
4434 },
4435 path: String,
4436 index: Number,
4437 lastFocused: {
4438 type: Object,
4439 notify: true
4440 },
4441 ironListTabIndex: {
4442 type: Number,
4443 observer: 'ironListTabIndexChanged_'
4444 }
4445 },
4446 row_: null,
4447 attached: function() {
4448 Polymer.RenderStatus.afterNextRender(this, function() {
4449 this.row_ = new HistoryFocusRow(this.$['sizing-container'], null, new Fo cusRowDelegate(this));
4450 this.row_.makeActive(this.ironListTabIndex == 0);
4451 this.listen(this, 'focus', 'onFocus_');
4452 this.listen(this, 'dom-change', 'onDomChange_');
4453 });
4454 },
4455 detached: function() {
4456 this.unlisten(this, 'focus', 'onFocus_');
4457 this.unlisten(this, 'dom-change', 'onDomChange_');
4458 if (this.row_) this.row_.destroy();
4459 },
4460 onFocus_: function() {
4461 if (this.lastFocused) this.row_.getEquivalentElement(this.lastFocused).foc us(); else this.row_.getFirstFocusable().focus();
4462 this.tabIndex = -1;
4463 },
4464 ironListTabIndexChanged_: function() {
4465 if (this.row_) this.row_.makeActive(this.ironListTabIndex == 0);
4466 },
4467 onDomChange_: function() {
4468 if (this.row_) this.row_.addItems();
4469 },
4470 onCheckboxSelected_: function(e) {
4471 this.fire('history-checkbox-select', {
4472 element: this,
4473 shiftKey: e.shiftKey
4474 });
4475 e.preventDefault();
4476 },
4477 onCheckboxMousedown_: function(e) {
4478 if (e.shiftKey) e.preventDefault();
4479 },
4480 getEntrySummary_: function() {
4481 var item = this.item;
4482 return loadTimeData.getStringF('entrySummary', item.dateTimeOfDay, item.st arred ? loadTimeData.getString('bookmarked') : '', item.title, item.domain);
4483 },
4484 getAriaChecked_: function(selected) {
4485 return selected ? 'true' : 'false';
4486 },
4487 onRemoveBookmarkTap_: function() {
4488 if (!this.item.starred) return;
4489 if (this.$$('#bookmark-star') == this.root.activeElement) this.$['menu-but ton'].focus();
4490 var browserService = md_history.BrowserService.getInstance();
4491 browserService.removeBookmark(this.item.url);
4492 browserService.recordAction('BookmarkStarClicked');
4493 this.fire('remove-bookmark-stars', this.item.url);
4494 },
4495 onMenuButtonTap_: function(e) {
4496 this.fire('toggle-menu', {
4497 target: Polymer.dom(e).localTarget,
4498 index: this.index,
4499 item: this.item,
4500 path: this.path
4501 });
4502 e.stopPropagation();
4503 },
4504 onLinkClick_: function() {
4505 var browserService = md_history.BrowserService.getInstance();
4506 browserService.recordAction('EntryLinkClick');
4507 if (this.searchTerm) browserService.recordAction('SearchResultClick');
4508 if (this.index == undefined) return;
4509 browserService.recordHistogram('HistoryPage.ClickPosition', this.index, UM A_MAX_BUCKET_VALUE);
4510 if (this.index <= UMA_MAX_SUBSET_BUCKET_VALUE) {
4511 browserService.recordHistogram('HistoryPage.ClickPositionSubset', this.i ndex, UMA_MAX_SUBSET_BUCKET_VALUE);
4512 }
4513 },
4514 onLinkRightClick_: function() {
4515 md_history.BrowserService.getInstance().recordAction('EntryLinkRightClick' );
4516 },
4517 showIcon_: function() {
4518 this.$.icon.style.backgroundImage = cr.icon.getFavicon(this.item.url);
4519 },
4520 selectionNotAllowed_: function() {
4521 return !loadTimeData.getBoolean('allowDeletingHistory');
4522 },
4523 cardTitle_: function(numberOfItems, historyDate, search) {
4524 if (!search) return this.item.dateRelativeDay;
4525 var resultId = numberOfItems == 1 ? 'searchResult' : 'searchResults';
4526 return loadTimeData.getStringF('foundSearchResults', numberOfItems, loadTi meData.getString(resultId), search);
4527 }
4528 });
4529 HistoryItem.needsTimeGap = function(visits, currentIndex, searchedTerm) {
4530 if (currentIndex >= visits.length - 1 || visits.length == 0) return false;
4531 var currentItem = visits[currentIndex];
4532 var nextItem = visits[currentIndex + 1];
4533 if (searchedTerm) return currentItem.dateShort != nextItem.dateShort;
4534 return currentItem.time - nextItem.time > BROWSING_GAP_TIME && currentItem.d ateRelativeDay == nextItem.dateRelativeDay;
4535 };
4536 return {
4537 HistoryItem: HistoryItem
4538 };
4539 });
4540
4541 // Copyright 2016 The Chromium Authors. All rights reserved. 63 // Copyright 2016 The Chromium Authors. All rights reserved.
4542 // Use of this source code is governed by a BSD-style license that can be 64 // Use of this source code is governed by a BSD-style license that can be
4543 // found in the LICENSE file. 65 // found in the LICENSE file.
4544 var SelectionTreeNode = function(currentPath) { 66 var SelectionTreeNode=function(currentPath){this.currentPath=currentPath;this.le af=false;this.indexes=[];this.children=[]};SelectionTreeNode.prototype.addChild= function(index,path){this.indexes.push(index);this.children[index]=new Selection TreeNode(path)};var HistoryListBehavior={properties:{selectedPaths:{type:Object, value:function(){return new Set}},lastSelectedPath:String},listeners:{"history-c heckbox-select":"itemSelected_"},hasResults:function(historyDataLength){return h istoryDataLength>0},noResultsMessage:function(searchedTerm,isLoading){if(isLoadi ng)return"";var messageId=searchedTerm!==""?"noSearchResults":"noResults";return loadTimeData.getString(messageId)},unselectAllItems:function(){this.selectedPat hs.forEach(function(path){this.set(path+".selected",false)}.bind(this));this.sel ectedPaths.clear()},deleteSelected:function(){var toBeRemoved=Array.from(this.se lectedPaths.values()).map(function(path){return this.get(path)}.bind(this));md_h istory.BrowserService.getInstance().deleteItems(toBeRemoved).then(function(){thi s.removeItemsByPath(Array.from(this.selectedPaths));this.fire("unselect-all")}.b ind(this))},removeItemsByPath:function(paths){if(paths.length==0)return;this.rem oveItemsBeneathNode_(this.buildRemovalTree_(paths))},buildRemovalTree_:function( paths){var rootNode=new SelectionTreeNode(paths[0].split(".")[0]);paths.forEach( function(path){var components=path.split(".");var node=rootNode;components.shift ();while(components.length>1){var index=Number(components.shift());var arrayName =components.shift();if(!node.children[index])node.addChild(index,[node.currentPa th,index,arrayName].join("."));node=node.children[index]}node.leaf=true;node.ind exes.push(Number(components.shift()))});return rootNode},removeItemsBeneathNode_ :function(node){var array=this.get(node.currentPath);var splices=[];node.indexes .sort(function(a,b){return b-a});node.indexes.forEach(function(index){if(node.le af||this.removeItemsBeneathNode_(node.children[index])){var item=array.splice(in dex,1)[0];splices.push({index:index,removed:[item],addedCount:0,object:array,typ e:"splice"})}}.bind(this));if(array.length==0&&node.currentPath.indexOf(".")!=-1 )return true;this.notifySplices(node.currentPath,splices);return false},itemSele cted_:function(e){var item=e.detail.element;var paths=[];var itemPath=item.path; if(e.detail.shiftKey&&this.lastSelectedPath){var itemPathComponents=itemPath.spl it(".");var itemIndex=Number(itemPathComponents.pop());var itemArrayPath=itemPat hComponents.join(".");var lastItemPathComponents=this.lastSelectedPath.split("." );var lastItemIndex=Number(lastItemPathComponents.pop());if(itemArrayPath==lastI temPathComponents.join(".")){for(var i=Math.min(itemIndex,lastItemIndex);i<=Math .max(itemIndex,lastItemIndex);i++){paths.push(itemArrayPath+"."+i)}}}if(paths.le ngth==0)paths.push(item.path);var selected=!this.selectedPaths.has(item.path);pa ths.forEach(function(path){this.set(path+".selected",selected);if(selected){this .selectedPaths.add(path);return}this.selectedPaths.delete(path)}.bind(this));thi s.lastSelectedPath=itemPath}};
4545 this.currentPath = currentPath;
4546 this.leaf = false;
4547 this.indexes = [];
4548 this.children = [];
4549 };
4550
4551 SelectionTreeNode.prototype.addChild = function(index, path) {
4552 this.indexes.push(index);
4553 this.children[index] = new SelectionTreeNode(path);
4554 };
4555
4556 var HistoryListBehavior = {
4557 properties: {
4558 selectedPaths: {
4559 type: Object,
4560 value: function() {
4561 return new Set();
4562 }
4563 },
4564 lastSelectedPath: String
4565 },
4566 listeners: {
4567 'history-checkbox-select': 'itemSelected_'
4568 },
4569 hasResults: function(historyDataLength) {
4570 return historyDataLength > 0;
4571 },
4572 noResultsMessage: function(searchedTerm, isLoading) {
4573 if (isLoading) return '';
4574 var messageId = searchedTerm !== '' ? 'noSearchResults' : 'noResults';
4575 return loadTimeData.getString(messageId);
4576 },
4577 unselectAllItems: function() {
4578 this.selectedPaths.forEach(function(path) {
4579 this.set(path + '.selected', false);
4580 }.bind(this));
4581 this.selectedPaths.clear();
4582 },
4583 deleteSelected: function() {
4584 var toBeRemoved = Array.from(this.selectedPaths.values()).map(function(path) {
4585 return this.get(path);
4586 }.bind(this));
4587 md_history.BrowserService.getInstance().deleteItems(toBeRemoved).then(functi on() {
4588 this.removeItemsByPath(Array.from(this.selectedPaths));
4589 this.fire('unselect-all');
4590 }.bind(this));
4591 },
4592 removeItemsByPath: function(paths) {
4593 if (paths.length == 0) return;
4594 this.removeItemsBeneathNode_(this.buildRemovalTree_(paths));
4595 },
4596 buildRemovalTree_: function(paths) {
4597 var rootNode = new SelectionTreeNode(paths[0].split('.')[0]);
4598 paths.forEach(function(path) {
4599 var components = path.split('.');
4600 var node = rootNode;
4601 components.shift();
4602 while (components.length > 1) {
4603 var index = Number(components.shift());
4604 var arrayName = components.shift();
4605 if (!node.children[index]) node.addChild(index, [ node.currentPath, inde x, arrayName ].join('.'));
4606 node = node.children[index];
4607 }
4608 node.leaf = true;
4609 node.indexes.push(Number(components.shift()));
4610 });
4611 return rootNode;
4612 },
4613 removeItemsBeneathNode_: function(node) {
4614 var array = this.get(node.currentPath);
4615 var splices = [];
4616 node.indexes.sort(function(a, b) {
4617 return b - a;
4618 });
4619 node.indexes.forEach(function(index) {
4620 if (node.leaf || this.removeItemsBeneathNode_(node.children[index])) {
4621 var item = array.splice(index, 1)[0];
4622 splices.push({
4623 index: index,
4624 removed: [ item ],
4625 addedCount: 0,
4626 object: array,
4627 type: 'splice'
4628 });
4629 }
4630 }.bind(this));
4631 if (array.length == 0 && node.currentPath.indexOf('.') != -1) return true;
4632 this.notifySplices(node.currentPath, splices);
4633 return false;
4634 },
4635 itemSelected_: function(e) {
4636 var item = e.detail.element;
4637 var paths = [];
4638 var itemPath = item.path;
4639 if (e.detail.shiftKey && this.lastSelectedPath) {
4640 var itemPathComponents = itemPath.split('.');
4641 var itemIndex = Number(itemPathComponents.pop());
4642 var itemArrayPath = itemPathComponents.join('.');
4643 var lastItemPathComponents = this.lastSelectedPath.split('.');
4644 var lastItemIndex = Number(lastItemPathComponents.pop());
4645 if (itemArrayPath == lastItemPathComponents.join('.')) {
4646 for (var i = Math.min(itemIndex, lastItemIndex); i <= Math.max(itemIndex , lastItemIndex); i++) {
4647 paths.push(itemArrayPath + '.' + i);
4648 }
4649 }
4650 }
4651 if (paths.length == 0) paths.push(item.path);
4652 var selected = !this.selectedPaths.has(item.path);
4653 paths.forEach(function(path) {
4654 this.set(path + '.selected', selected);
4655 if (selected) {
4656 this.selectedPaths.add(path);
4657 return;
4658 }
4659 this.selectedPaths.delete(path);
4660 }.bind(this));
4661 this.lastSelectedPath = itemPath;
4662 }
4663 };
4664
4665 // Copyright 2015 The Chromium Authors. All rights reserved. 67 // Copyright 2015 The Chromium Authors. All rights reserved.
4666 // Use of this source code is governed by a BSD-style license that can be 68 // Use of this source code is governed by a BSD-style license that can be
4667 // found in the LICENSE file. 69 // found in the LICENSE file.
4668 Polymer({ 70 Polymer({is:"history-list",behaviors:[HistoryListBehavior],properties:{searchedT erm:{type:String,value:""},querying:Boolean,historyData_:Array,resultLoadingDisa bled_:{type:Boolean,value:false},lastFocused_:Object},listeners:{scroll:"notifyL istScroll_","remove-bookmark-stars":"removeBookmarkStars_"},attached:function(){ this.$["infinite-list"].notifyResize();this.$["infinite-list"].scrollTarget=this ;this.$["scroll-threshold"].scrollTarget=this},removeBookmarkStars_:function(e){ var url=e.detail;if(this.historyData_===undefined)return;for(var i=0;i<this.hist oryData_.length;i++){if(this.historyData_[i].url==url)this.set("historyData_."+i +".starred",false)}},disableResultLoading:function(){this.resultLoadingDisabled_ =true},addNewResults:function(historyResults,incremental){var results=historyRes ults.slice();this.$["scroll-threshold"].clearTriggers();if(!incremental){this.re sultLoadingDisabled_=false;if(this.historyData_)this.splice("historyData_",0,thi s.historyData_.length);this.fire("unselect-all")}if(this.historyData_){results.u nshift("historyData_");this.push.apply(this,results)}else{this.set("historyData_ ",results)}},loadMoreData_:function(){if(this.resultLoadingDisabled_||this.query ing)return;this.fire("load-more-history")},needsTimeGap_:function(item,index,len gth){return md_history.HistoryItem.needsTimeGap(this.historyData_,index,this.sea rchedTerm)},isCardStart_:function(item,i,length){if(length==0||i>length-1)return false;return i==0||this.historyData_[i].dateRelativeDay!=this.historyData_[i-1] .dateRelativeDay},isCardEnd_:function(item,i,length){if(length==0||i>length-1)re turn false;return i==length-1||this.historyData_[i].dateRelativeDay!=this.histor yData_[i+1].dateRelativeDay},notifyListScroll_:function(){this.fire("history-lis t-scrolled")},pathForItem_:function(index){return"historyData_."+index}});
4669 is: 'history-list',
4670 behaviors: [ HistoryListBehavior ],
4671 properties: {
4672 searchedTerm: {
4673 type: String,
4674 value: ''
4675 },
4676 querying: Boolean,
4677 historyData_: Array,
4678 resultLoadingDisabled_: {
4679 type: Boolean,
4680 value: false
4681 },
4682 lastFocused_: Object
4683 },
4684 listeners: {
4685 scroll: 'notifyListScroll_',
4686 'remove-bookmark-stars': 'removeBookmarkStars_'
4687 },
4688 attached: function() {
4689 this.$['infinite-list'].notifyResize();
4690 this.$['infinite-list'].scrollTarget = this;
4691 this.$['scroll-threshold'].scrollTarget = this;
4692 },
4693 removeBookmarkStars_: function(e) {
4694 var url = e.detail;
4695 if (this.historyData_ === undefined) return;
4696 for (var i = 0; i < this.historyData_.length; i++) {
4697 if (this.historyData_[i].url == url) this.set('historyData_.' + i + '.star red', false);
4698 }
4699 },
4700 disableResultLoading: function() {
4701 this.resultLoadingDisabled_ = true;
4702 },
4703 addNewResults: function(historyResults, incremental) {
4704 var results = historyResults.slice();
4705 this.$['scroll-threshold'].clearTriggers();
4706 if (!incremental) {
4707 this.resultLoadingDisabled_ = false;
4708 if (this.historyData_) this.splice('historyData_', 0, this.historyData_.le ngth);
4709 this.fire('unselect-all');
4710 }
4711 if (this.historyData_) {
4712 results.unshift('historyData_');
4713 this.push.apply(this, results);
4714 } else {
4715 this.set('historyData_', results);
4716 }
4717 },
4718 loadMoreData_: function() {
4719 if (this.resultLoadingDisabled_ || this.querying) return;
4720 this.fire('load-more-history');
4721 },
4722 needsTimeGap_: function(item, index, length) {
4723 return md_history.HistoryItem.needsTimeGap(this.historyData_, index, this.se archedTerm);
4724 },
4725 isCardStart_: function(item, i, length) {
4726 if (length == 0 || i > length - 1) return false;
4727 return i == 0 || this.historyData_[i].dateRelativeDay != this.historyData_[i - 1].dateRelativeDay;
4728 },
4729 isCardEnd_: function(item, i, length) {
4730 if (length == 0 || i > length - 1) return false;
4731 return i == length - 1 || this.historyData_[i].dateRelativeDay != this.histo ryData_[i + 1].dateRelativeDay;
4732 },
4733 notifyListScroll_: function() {
4734 this.fire('history-list-scrolled');
4735 },
4736 pathForItem_: function(index) {
4737 return 'historyData_.' + index;
4738 }
4739 });
4740
4741 // Copyright 2016 The Chromium Authors. All rights reserved. 71 // Copyright 2016 The Chromium Authors. All rights reserved.
4742 // Use of this source code is governed by a BSD-style license that can be 72 // Use of this source code is governed by a BSD-style license that can be
4743 // found in the LICENSE file. 73 // found in the LICENSE file.
4744 Polymer({ 74 Polymer({is:"history-list-container",properties:{selectedPage_:String,grouped:Bo olean,groupedRange:{type:Number,observer:"groupedRangeChanged_"},queryState:Obje ct,queryResult:Object},observers:["searchTermChanged_(queryState.searchTerm)"],l isteners:{"history-list-scrolled":"closeMenu_","load-more-history":"loadMoreHist ory_","toggle-menu":"toggleMenu_"},historyResult:function(info,results){this.ini tializeResults_(info,results);this.closeMenu_();if(this.selectedPage_=="grouped- list"){this.$$("#grouped-list").historyData=results;return}var list=this.$["infi nite-list"];list.addNewResults(results,this.queryState.incremental);if(info.fini shed)list.disableResultLoading()},queryHistory:function(incremental){var querySt ate=this.queryState;var noResults=!this.queryResult||this.queryResult.results==n ull;if(queryState.queryingDisabled||!this.queryState.searchTerm&&noResults){retu rn}var dialog=this.$.dialog.getIfExists();if(!incremental&&dialog&&dialog.open)d ialog.close();this.set("queryState.querying",true);this.set("queryState.incremen tal",incremental);var lastVisitTime=0;if(incremental){var lastVisit=this.queryRe sult.results.slice(-1)[0];lastVisitTime=lastVisit?lastVisit.time:0}var maxResult s=this.groupedRange==HistoryRange.ALL_TIME?RESULTS_PER_PAGE:0;chrome.send("query History",[queryState.searchTerm,queryState.groupedOffset,queryState.range,lastVi sitTime,maxResults])},historyDeleted:function(){if(this.getSelectedItemCount()>0 )return;this.queryHistory(false)},getContentScrollTarget:function(){return this. getSelectedList_()},getSelectedItemCount:function(){return this.getSelectedList_ ().selectedPaths.size},unselectAllItems:function(count){var selectedList=this.ge tSelectedList_();if(selectedList)selectedList.unselectAllItems(count)},deleteSel ectedWithPrompt:function(){if(!loadTimeData.getBoolean("allowDeletingHistory"))r eturn;var browserService=md_history.BrowserService.getInstance();browserService. recordAction("RemoveSelected");if(this.queryState.searchTerm!="")browserService. recordAction("SearchResultRemove");this.$.dialog.get().showModal()},groupedRange Changed_:function(range,oldRange){this.selectedPage_=range==HistoryRange.ALL_TIM E?"infinite-list":"grouped-list";if(oldRange==undefined)return;this.queryHistory (false);this.fire("history-view-changed")},searchTermChanged_:function(){this.qu eryHistory(false);if(this.queryState.searchTerm)md_history.BrowserService.getIns tance().recordAction("Search")},loadMoreHistory_:function(){this.queryHistory(tr ue)},initializeResults_:function(info,results){if(results.length==0)return;var c urrentDate=results[0].dateRelativeDay;for(var i=0;i<results.length;i++){results[ i].selected=false;results[i].readableTimestamp=info.term==""?results[i].dateTime OfDay:results[i].dateShort;if(results[i].dateRelativeDay!=currentDate){currentDa te=results[i].dateRelativeDay}}},onDialogConfirmTap_:function(){md_history.Brows erService.getInstance().recordAction("ConfirmRemoveSelected");this.getSelectedLi st_().deleteSelected();var dialog=assert(this.$.dialog.getIfExists());dialog.clo se()},onDialogCancelTap_:function(){md_history.BrowserService.getInstance().reco rdAction("CancelRemoveSelected");var dialog=assert(this.$.dialog.getIfExists()); dialog.close()},closeMenu_:function(){var menu=this.$.sharedMenu.getIfExists();i f(menu)menu.closeMenu()},toggleMenu_:function(e){var target=e.detail.target;var menu=this.$.sharedMenu.get();menu.toggleMenu(target,e.detail)},onMoreFromSiteTap _:function(){md_history.BrowserService.getInstance().recordAction("EntryMenuShow MoreFromSite");var menu=assert(this.$.sharedMenu.getIfExists());this.set("queryS tate.searchTerm",menu.itemData.item.domain);menu.closeMenu()},onRemoveFromHistor yTap_:function(){var browserService=md_history.BrowserService.getInstance();brow serService.recordAction("EntryMenuRemoveFromHistory");var menu=assert(this.$.sha redMenu.getIfExists());var itemData=menu.itemData;browserService.deleteItems([it emData.item]).then(function(items){this.getSelectedList_().removeItemsByPath([it emData.path]);this.fire("unselect-all");var index=itemData.index;if(index==undef ined)return;var browserService=md_history.BrowserService.getInstance();browserSe rvice.recordHistogram("HistoryPage.RemoveEntryPosition",index,UMA_MAX_BUCKET_VAL UE);if(index<=UMA_MAX_SUBSET_BUCKET_VALUE){browserService.recordHistogram("Histo ryPage.RemoveEntryPositionSubset",index,UMA_MAX_SUBSET_BUCKET_VALUE)}}.bind(this ));menu.closeMenu()},getSelectedList_:function(){return this.$.content.selectedI tem}});(function(){"use strict";Polymer({is:"iron-location",properties:{path:{ty pe:String,notify:true,value:function(){return window.decodeURIComponent(window.l ocation.pathname)}},query:{type:String,notify:true,value:function(){return windo w.decodeURIComponent(window.location.search.slice(1))}},hash:{type:String,notify :true,value:function(){return window.decodeURIComponent(window.location.hash.sli ce(1))}},dwellTime:{type:Number,value:2e3},urlSpaceRegex:{type:String,value:""}, _urlSpaceRegExp:{computed:"_makeRegExp(urlSpaceRegex)"},_lastChangedAt:{type:Num ber},_initialized:{type:Boolean,value:false}},hostAttributes:{hidden:true},obser vers:["_updateUrl(path, query, hash)"],attached:function(){this.listen(window,"h ashchange","_hashChanged");this.listen(window,"location-changed","_urlChanged"); this.listen(window,"popstate","_urlChanged");this.listen(document.body,"click"," _globalOnClick");this._lastChangedAt=window.performance.now()-(this.dwellTime-20 0);this._initialized=true;this._urlChanged()},detached:function(){this.unlisten( window,"hashchange","_hashChanged");this.unlisten(window,"location-changed","_ur lChanged");this.unlisten(window,"popstate","_urlChanged");this.unlisten(document .body,"click","_globalOnClick");this._initialized=false},_hashChanged:function() {this.hash=window.decodeURIComponent(window.location.hash.substring(1))},_urlCha nged:function(){this._dontUpdateUrl=true;this._hashChanged();this.path=window.de codeURIComponent(window.location.pathname);this.query=window.decodeURIComponent( window.location.search.substring(1));this._dontUpdateUrl=false;this._updateUrl() },_getUrl:function(){var partiallyEncodedPath=window.encodeURI(this.path).replac e(/\#/g,"%23").replace(/\?/g,"%3F");var partiallyEncodedQuery="";if(this.query){ partiallyEncodedQuery="?"+window.encodeURI(this.query).replace(/\#/g,"%23")}var partiallyEncodedHash="";if(this.hash){partiallyEncodedHash="#"+window.encodeURI( this.hash)}return partiallyEncodedPath+partiallyEncodedQuery+partiallyEncodedHas h},_updateUrl:function(){if(this._dontUpdateUrl||!this._initialized){return}if(t his.path===window.decodeURIComponent(window.location.pathname)&&this.query===win dow.decodeURIComponent(window.location.search.substring(1))&&this.hash===window. decodeURIComponent(window.location.hash.substring(1))){return}var newUrl=this._g etUrl();var fullNewUrl=new URL(newUrl,window.location.protocol+"//"+window.locat ion.host).href;var now=window.performance.now();var shouldReplace=this._lastChan gedAt+this.dwellTime>now;this._lastChangedAt=now;if(shouldReplace){window.histor y.replaceState({},"",fullNewUrl)}else{window.history.pushState({},"",fullNewUrl) }this.fire("location-changed",{},{node:window})},_globalOnClick:function(event){ if(event.defaultPrevented){return}var href=this._getSameOriginLinkHref(event);if (!href){return}event.preventDefault();if(href===window.location.href){return}win dow.history.pushState({},"",href);this.fire("location-changed",{},{node:window}) },_getSameOriginLinkHref:function(event){if(event.button!==0){return null}if(eve nt.metaKey||event.ctrlKey){return null}var eventPath=Polymer.dom(event).path;var anchor=null;for(var i=0;i<eventPath.length;i++){var element=eventPath[i];if(ele ment.tagName==="A"&&element.href){anchor=element;break}}if(!anchor){return null} if(anchor.target==="_blank"){return null}if((anchor.target==="_top"||anchor.targ et==="_parent")&&window.top!==window){return null}var href=anchor.href;var url;i f(document.baseURI!=null){url=new URL(href,document.baseURI)}else{url=new URL(hr ef)}var origin;if(window.location.origin){origin=window.location.origin}else{ori gin=window.location.protocol+"//"+window.location.hostname;if(window.location.po rt){origin+=":"+window.location.port}}if(url.origin!==origin){return null}var no rmalizedHref=url.pathname+url.search+url.hash;if(this._urlSpaceRegExp&&!this._ur lSpaceRegExp.test(normalizedHref)){return null}var fullNormalizedHref=new URL(no rmalizedHref,window.location.href).href;return fullNormalizedHref},_makeRegExp:f unction(urlSpaceRegex){return RegExp(urlSpaceRegex)}})})();"use strict";Polymer( {is:"iron-query-params",properties:{paramsString:{type:String,notify:true,observ er:"paramsStringChanged"},paramsObject:{type:Object,notify:true,value:function() {return{}}},_dontReact:{type:Boolean,value:false}},hostAttributes:{hidden:true}, observers:["paramsObjectChanged(paramsObject.*)"],paramsStringChanged:function() {this._dontReact=true;this.paramsObject=this._decodeParams(this.paramsString);th is._dontReact=false},paramsObjectChanged:function(){if(this._dontReact){return}t his.paramsString=this._encodeParams(this.paramsObject)},_encodeParams:function(p arams){var encodedParams=[];for(var key in params){var value=params[key];if(valu e===""){encodedParams.push(encodeURIComponent(key))}else if(value){encodedParams .push(encodeURIComponent(key)+"="+encodeURIComponent(value.toString()))}}return encodedParams.join("&")},_decodeParams:function(paramString){var params={};param String=(paramString||"").replace(/\+/g,"%20");var paramList=paramString.split("& ");for(var i=0;i<paramList.length;i++){var param=paramList[i].split("=");if(para m[0]){params[decodeURIComponent(param[0])]=decodeURIComponent(param[1]||"")}}ret urn params}});
4745 is: 'history-list-container',
4746 properties: {
4747 selectedPage_: String,
4748 grouped: Boolean,
4749 groupedRange: {
4750 type: Number,
4751 observer: 'groupedRangeChanged_'
4752 },
4753 queryState: Object,
4754 queryResult: Object
4755 },
4756 observers: [ 'searchTermChanged_(queryState.searchTerm)' ],
4757 listeners: {
4758 'history-list-scrolled': 'closeMenu_',
4759 'load-more-history': 'loadMoreHistory_',
4760 'toggle-menu': 'toggleMenu_'
4761 },
4762 historyResult: function(info, results) {
4763 this.initializeResults_(info, results);
4764 this.closeMenu_();
4765 if (this.selectedPage_ == 'grouped-list') {
4766 this.$$('#grouped-list').historyData = results;
4767 return;
4768 }
4769 var list = this.$['infinite-list'];
4770 list.addNewResults(results, this.queryState.incremental);
4771 if (info.finished) list.disableResultLoading();
4772 },
4773 queryHistory: function(incremental) {
4774 var queryState = this.queryState;
4775 var noResults = !this.queryResult || this.queryResult.results == null;
4776 if (queryState.queryingDisabled || !this.queryState.searchTerm && noResults) {
4777 return;
4778 }
4779 var dialog = this.$.dialog.getIfExists();
4780 if (!incremental && dialog && dialog.open) dialog.close();
4781 this.set('queryState.querying', true);
4782 this.set('queryState.incremental', incremental);
4783 var lastVisitTime = 0;
4784 if (incremental) {
4785 var lastVisit = this.queryResult.results.slice(-1)[0];
4786 lastVisitTime = lastVisit ? lastVisit.time : 0;
4787 }
4788 var maxResults = this.groupedRange == HistoryRange.ALL_TIME ? RESULTS_PER_PA GE : 0;
4789 chrome.send('queryHistory', [ queryState.searchTerm, queryState.groupedOffse t, queryState.range, lastVisitTime, maxResults ]);
4790 },
4791 historyDeleted: function() {
4792 if (this.getSelectedItemCount() > 0) return;
4793 this.queryHistory(false);
4794 },
4795 getContentScrollTarget: function() {
4796 return this.getSelectedList_();
4797 },
4798 getSelectedItemCount: function() {
4799 return this.getSelectedList_().selectedPaths.size;
4800 },
4801 unselectAllItems: function(count) {
4802 var selectedList = this.getSelectedList_();
4803 if (selectedList) selectedList.unselectAllItems(count);
4804 },
4805 deleteSelectedWithPrompt: function() {
4806 if (!loadTimeData.getBoolean('allowDeletingHistory')) return;
4807 var browserService = md_history.BrowserService.getInstance();
4808 browserService.recordAction('RemoveSelected');
4809 if (this.queryState.searchTerm != '') browserService.recordAction('SearchRes ultRemove');
4810 this.$.dialog.get().showModal();
4811 },
4812 groupedRangeChanged_: function(range, oldRange) {
4813 this.selectedPage_ = range == HistoryRange.ALL_TIME ? 'infinite-list' : 'gro uped-list';
4814 if (oldRange == undefined) return;
4815 this.queryHistory(false);
4816 this.fire('history-view-changed');
4817 },
4818 searchTermChanged_: function() {
4819 this.queryHistory(false);
4820 if (this.queryState.searchTerm) md_history.BrowserService.getInstance().reco rdAction('Search');
4821 },
4822 loadMoreHistory_: function() {
4823 this.queryHistory(true);
4824 },
4825 initializeResults_: function(info, results) {
4826 if (results.length == 0) return;
4827 var currentDate = results[0].dateRelativeDay;
4828 for (var i = 0; i < results.length; i++) {
4829 results[i].selected = false;
4830 results[i].readableTimestamp = info.term == '' ? results[i].dateTimeOfDay : results[i].dateShort;
4831 if (results[i].dateRelativeDay != currentDate) {
4832 currentDate = results[i].dateRelativeDay;
4833 }
4834 }
4835 },
4836 onDialogConfirmTap_: function() {
4837 md_history.BrowserService.getInstance().recordAction('ConfirmRemoveSelected' );
4838 this.getSelectedList_().deleteSelected();
4839 var dialog = assert(this.$.dialog.getIfExists());
4840 dialog.close();
4841 },
4842 onDialogCancelTap_: function() {
4843 md_history.BrowserService.getInstance().recordAction('CancelRemoveSelected') ;
4844 var dialog = assert(this.$.dialog.getIfExists());
4845 dialog.close();
4846 },
4847 closeMenu_: function() {
4848 var menu = this.$.sharedMenu.getIfExists();
4849 if (menu) menu.closeMenu();
4850 },
4851 toggleMenu_: function(e) {
4852 var target = e.detail.target;
4853 var menu = this.$.sharedMenu.get();
4854 menu.toggleMenu(target, e.detail);
4855 },
4856 onMoreFromSiteTap_: function() {
4857 md_history.BrowserService.getInstance().recordAction('EntryMenuShowMoreFromS ite');
4858 var menu = assert(this.$.sharedMenu.getIfExists());
4859 this.set('queryState.searchTerm', menu.itemData.item.domain);
4860 menu.closeMenu();
4861 },
4862 onRemoveFromHistoryTap_: function() {
4863 var browserService = md_history.BrowserService.getInstance();
4864 browserService.recordAction('EntryMenuRemoveFromHistory');
4865 var menu = assert(this.$.sharedMenu.getIfExists());
4866 var itemData = menu.itemData;
4867 browserService.deleteItems([ itemData.item ]).then(function(items) {
4868 this.getSelectedList_().removeItemsByPath([ itemData.path ]);
4869 this.fire('unselect-all');
4870 var index = itemData.index;
4871 if (index == undefined) return;
4872 var browserService = md_history.BrowserService.getInstance();
4873 browserService.recordHistogram('HistoryPage.RemoveEntryPosition', index, U MA_MAX_BUCKET_VALUE);
4874 if (index <= UMA_MAX_SUBSET_BUCKET_VALUE) {
4875 browserService.recordHistogram('HistoryPage.RemoveEntryPositionSubset', index, UMA_MAX_SUBSET_BUCKET_VALUE);
4876 }
4877 }.bind(this));
4878 menu.closeMenu();
4879 },
4880 getSelectedList_: function() {
4881 return this.$.content.selectedItem;
4882 }
4883 });
4884
4885 (function() {
4886 'use strict';
4887 Polymer({
4888 is: 'iron-location',
4889 properties: {
4890 path: {
4891 type: String,
4892 notify: true,
4893 value: function() {
4894 return window.decodeURIComponent(window.location.pathname);
4895 }
4896 },
4897 query: {
4898 type: String,
4899 notify: true,
4900 value: function() {
4901 return window.decodeURIComponent(window.location.search.slice(1));
4902 }
4903 },
4904 hash: {
4905 type: String,
4906 notify: true,
4907 value: function() {
4908 return window.decodeURIComponent(window.location.hash.slice(1));
4909 }
4910 },
4911 dwellTime: {
4912 type: Number,
4913 value: 2e3
4914 },
4915 urlSpaceRegex: {
4916 type: String,
4917 value: ''
4918 },
4919 _urlSpaceRegExp: {
4920 computed: '_makeRegExp(urlSpaceRegex)'
4921 },
4922 _lastChangedAt: {
4923 type: Number
4924 },
4925 _initialized: {
4926 type: Boolean,
4927 value: false
4928 }
4929 },
4930 hostAttributes: {
4931 hidden: true
4932 },
4933 observers: [ '_updateUrl(path, query, hash)' ],
4934 attached: function() {
4935 this.listen(window, 'hashchange', '_hashChanged');
4936 this.listen(window, 'location-changed', '_urlChanged');
4937 this.listen(window, 'popstate', '_urlChanged');
4938 this.listen(document.body, 'click', '_globalOnClick');
4939 this._lastChangedAt = window.performance.now() - (this.dwellTime - 200);
4940 this._initialized = true;
4941 this._urlChanged();
4942 },
4943 detached: function() {
4944 this.unlisten(window, 'hashchange', '_hashChanged');
4945 this.unlisten(window, 'location-changed', '_urlChanged');
4946 this.unlisten(window, 'popstate', '_urlChanged');
4947 this.unlisten(document.body, 'click', '_globalOnClick');
4948 this._initialized = false;
4949 },
4950 _hashChanged: function() {
4951 this.hash = window.decodeURIComponent(window.location.hash.substring(1));
4952 },
4953 _urlChanged: function() {
4954 this._dontUpdateUrl = true;
4955 this._hashChanged();
4956 this.path = window.decodeURIComponent(window.location.pathname);
4957 this.query = window.decodeURIComponent(window.location.search.substring(1) );
4958 this._dontUpdateUrl = false;
4959 this._updateUrl();
4960 },
4961 _getUrl: function() {
4962 var partiallyEncodedPath = window.encodeURI(this.path).replace(/\#/g, '%23 ').replace(/\?/g, '%3F');
4963 var partiallyEncodedQuery = '';
4964 if (this.query) {
4965 partiallyEncodedQuery = '?' + window.encodeURI(this.query).replace(/\#/g , '%23');
4966 }
4967 var partiallyEncodedHash = '';
4968 if (this.hash) {
4969 partiallyEncodedHash = '#' + window.encodeURI(this.hash);
4970 }
4971 return partiallyEncodedPath + partiallyEncodedQuery + partiallyEncodedHash ;
4972 },
4973 _updateUrl: function() {
4974 if (this._dontUpdateUrl || !this._initialized) {
4975 return;
4976 }
4977 if (this.path === window.decodeURIComponent(window.location.pathname) && t his.query === window.decodeURIComponent(window.location.search.substring(1)) && this.hash === window.decodeURIComponent(window.location.hash.substring(1))) {
4978 return;
4979 }
4980 var newUrl = this._getUrl();
4981 var fullNewUrl = new URL(newUrl, window.location.protocol + '//' + window. location.host).href;
4982 var now = window.performance.now();
4983 var shouldReplace = this._lastChangedAt + this.dwellTime > now;
4984 this._lastChangedAt = now;
4985 if (shouldReplace) {
4986 window.history.replaceState({}, '', fullNewUrl);
4987 } else {
4988 window.history.pushState({}, '', fullNewUrl);
4989 }
4990 this.fire('location-changed', {}, {
4991 node: window
4992 });
4993 },
4994 _globalOnClick: function(event) {
4995 if (event.defaultPrevented) {
4996 return;
4997 }
4998 var href = this._getSameOriginLinkHref(event);
4999 if (!href) {
5000 return;
5001 }
5002 event.preventDefault();
5003 if (href === window.location.href) {
5004 return;
5005 }
5006 window.history.pushState({}, '', href);
5007 this.fire('location-changed', {}, {
5008 node: window
5009 });
5010 },
5011 _getSameOriginLinkHref: function(event) {
5012 if (event.button !== 0) {
5013 return null;
5014 }
5015 if (event.metaKey || event.ctrlKey) {
5016 return null;
5017 }
5018 var eventPath = Polymer.dom(event).path;
5019 var anchor = null;
5020 for (var i = 0; i < eventPath.length; i++) {
5021 var element = eventPath[i];
5022 if (element.tagName === 'A' && element.href) {
5023 anchor = element;
5024 break;
5025 }
5026 }
5027 if (!anchor) {
5028 return null;
5029 }
5030 if (anchor.target === '_blank') {
5031 return null;
5032 }
5033 if ((anchor.target === '_top' || anchor.target === '_parent') && window.to p !== window) {
5034 return null;
5035 }
5036 var href = anchor.href;
5037 var url;
5038 if (document.baseURI != null) {
5039 url = new URL(href, document.baseURI);
5040 } else {
5041 url = new URL(href);
5042 }
5043 var origin;
5044 if (window.location.origin) {
5045 origin = window.location.origin;
5046 } else {
5047 origin = window.location.protocol + '//' + window.location.hostname;
5048 if (window.location.port) {
5049 origin += ':' + window.location.port;
5050 }
5051 }
5052 if (url.origin !== origin) {
5053 return null;
5054 }
5055 var normalizedHref = url.pathname + url.search + url.hash;
5056 if (this._urlSpaceRegExp && !this._urlSpaceRegExp.test(normalizedHref)) {
5057 return null;
5058 }
5059 var fullNormalizedHref = new URL(normalizedHref, window.location.href).hre f;
5060 return fullNormalizedHref;
5061 },
5062 _makeRegExp: function(urlSpaceRegex) {
5063 return RegExp(urlSpaceRegex);
5064 }
5065 });
5066 })();
5067
5068 'use strict';
5069
5070 Polymer({
5071 is: 'iron-query-params',
5072 properties: {
5073 paramsString: {
5074 type: String,
5075 notify: true,
5076 observer: 'paramsStringChanged'
5077 },
5078 paramsObject: {
5079 type: Object,
5080 notify: true,
5081 value: function() {
5082 return {};
5083 }
5084 },
5085 _dontReact: {
5086 type: Boolean,
5087 value: false
5088 }
5089 },
5090 hostAttributes: {
5091 hidden: true
5092 },
5093 observers: [ 'paramsObjectChanged(paramsObject.*)' ],
5094 paramsStringChanged: function() {
5095 this._dontReact = true;
5096 this.paramsObject = this._decodeParams(this.paramsString);
5097 this._dontReact = false;
5098 },
5099 paramsObjectChanged: function() {
5100 if (this._dontReact) {
5101 return;
5102 }
5103 this.paramsString = this._encodeParams(this.paramsObject);
5104 },
5105 _encodeParams: function(params) {
5106 var encodedParams = [];
5107 for (var key in params) {
5108 var value = params[key];
5109 if (value === '') {
5110 encodedParams.push(encodeURIComponent(key));
5111 } else if (value) {
5112 encodedParams.push(encodeURIComponent(key) + '=' + encodeURIComponent(va lue.toString()));
5113 }
5114 }
5115 return encodedParams.join('&');
5116 },
5117 _decodeParams: function(paramString) {
5118 var params = {};
5119 paramString = (paramString || '').replace(/\+/g, '%20');
5120 var paramList = paramString.split('&');
5121 for (var i = 0; i < paramList.length; i++) {
5122 var param = paramList[i].split('=');
5123 if (param[0]) {
5124 params[decodeURIComponent(param[0])] = decodeURIComponent(param[1] || '' );
5125 }
5126 }
5127 return params;
5128 }
5129 });
5130
5131 // Copyright 2016 The Chromium Authors. All rights reserved. 75 // Copyright 2016 The Chromium Authors. All rights reserved.
5132 // Use of this source code is governed by a BSD-style license that can be 76 // Use of this source code is governed by a BSD-style license that can be
5133 // found in the LICENSE file. 77 // found in the LICENSE file.
5134 Polymer({ 78 Polymer({is:"history-router",properties:{selectedPage:{type:String,observer:"ser ializePath_",notify:true},queryState:{type:Object,notify:true},path_:{type:Strin g,observer:"pathChanged_"},queryParams_:Object},observers:["queryParamsChanged_( queryParams_.*)","searchTermChanged_(queryState.searchTerm)"],attached:function( ){if(window.location.hash){window.location.href=window.location.href.split("#")[ 0]+"?"+window.location.hash.substr(1)}},serializePath_:function(){var page=this. selectedPage=="history"?"":this.selectedPage;this.path_="/"+page},pathChanged_:f unction(){var sections=this.path_.substr(1).split("/");this.selectedPage=section s[0]||"history"},queryParamsChanged_:function(){this.set("queryState.searchTerm" ,this.queryParams_.q||"")},searchTermChanged_:function(){this.set("queryParams_. q",this.queryState.searchTerm||null)}});Polymer.IronMultiSelectableBehaviorImpl= {properties:{multi:{type:Boolean,value:false,observer:"multiChanged"},selectedVa lues:{type:Array,notify:true},selectedItems:{type:Array,readOnly:true,notify:tru e}},observers:["_updateSelected(selectedValues.splices)"],select:function(value) {if(this.multi){if(this.selectedValues){this._toggleSelected(value)}else{this.se lectedValues=[value]}}else{this.selected=value}},multiChanged:function(multi){th is._selection.multi=multi},get _shouldUpdateSelection(){return this.selected!=nu ll||this.selectedValues!=null&&this.selectedValues.length},_updateAttrForSelecte d:function(){if(!this.multi){Polymer.IronSelectableBehavior._updateAttrForSelect ed.apply(this)}else if(this._shouldUpdateSelection){this.selectedValues=this.sel ectedItems.map(function(selectedItem){return this._indexToValue(this.indexOf(sel ectedItem))},this).filter(function(unfilteredValue){return unfilteredValue!=null },this)}},_updateSelected:function(){if(this.multi){this._selectMulti(this.selec tedValues)}else{this._selectSelected(this.selected)}},_selectMulti:function(valu es){if(values){var selectedItems=this._valuesToItems(values);this._selection.cle ar(selectedItems);for(var i=0;i<selectedItems.length;i++){this._selection.setIte mSelected(selectedItems[i],true)}if(this.fallbackSelection&&this.items.length&&! this._selection.get().length){var fallback=this._valueToItem(this.fallbackSelect ion);if(fallback){this.selectedValues=[this.fallbackSelection]}}}else{this._sele ction.clear()}},_selectionChange:function(){var s=this._selection.get();if(this. multi){this._setSelectedItems(s)}else{this._setSelectedItems([s]);this._setSelec tedItem(s)}},_toggleSelected:function(value){var i=this.selectedValues.indexOf(v alue);var unselected=i<0;if(unselected){this.push("selectedValues",value)}else{t his.splice("selectedValues",i,1)}},_valuesToItems:function(values){return values ==null?null:values.map(function(value){return this._valueToItem(value)},this)}}; Polymer.IronMultiSelectableBehavior=[Polymer.IronSelectableBehavior,Polymer.Iron MultiSelectableBehaviorImpl];Polymer({is:"iron-selector",behaviors:[Polymer.Iron MultiSelectableBehavior]});
5135 is: 'history-router',
5136 properties: {
5137 selectedPage: {
5138 type: String,
5139 observer: 'serializePath_',
5140 notify: true
5141 },
5142 queryState: {
5143 type: Object,
5144 notify: true
5145 },
5146 path_: {
5147 type: String,
5148 observer: 'pathChanged_'
5149 },
5150 queryParams_: Object
5151 },
5152 observers: [ 'queryParamsChanged_(queryParams_.*)', 'searchTermChanged_(queryS tate.searchTerm)' ],
5153 attached: function() {
5154 if (window.location.hash) {
5155 window.location.href = window.location.href.split('#')[0] + '?' + window.l ocation.hash.substr(1);
5156 }
5157 },
5158 serializePath_: function() {
5159 var page = this.selectedPage == 'history' ? '' : this.selectedPage;
5160 this.path_ = '/' + page;
5161 },
5162 pathChanged_: function() {
5163 var sections = this.path_.substr(1).split('/');
5164 this.selectedPage = sections[0] || 'history';
5165 },
5166 queryParamsChanged_: function() {
5167 this.set('queryState.searchTerm', this.queryParams_.q || '');
5168 },
5169 searchTermChanged_: function() {
5170 this.set('queryParams_.q', this.queryState.searchTerm || null);
5171 }
5172 });
5173
5174 Polymer.IronMultiSelectableBehaviorImpl = {
5175 properties: {
5176 multi: {
5177 type: Boolean,
5178 value: false,
5179 observer: 'multiChanged'
5180 },
5181 selectedValues: {
5182 type: Array,
5183 notify: true
5184 },
5185 selectedItems: {
5186 type: Array,
5187 readOnly: true,
5188 notify: true
5189 }
5190 },
5191 observers: [ '_updateSelected(selectedValues.splices)' ],
5192 select: function(value) {
5193 if (this.multi) {
5194 if (this.selectedValues) {
5195 this._toggleSelected(value);
5196 } else {
5197 this.selectedValues = [ value ];
5198 }
5199 } else {
5200 this.selected = value;
5201 }
5202 },
5203 multiChanged: function(multi) {
5204 this._selection.multi = multi;
5205 },
5206 get _shouldUpdateSelection() {
5207 return this.selected != null || this.selectedValues != null && this.selected Values.length;
5208 },
5209 _updateAttrForSelected: function() {
5210 if (!this.multi) {
5211 Polymer.IronSelectableBehavior._updateAttrForSelected.apply(this);
5212 } else if (this._shouldUpdateSelection) {
5213 this.selectedValues = this.selectedItems.map(function(selectedItem) {
5214 return this._indexToValue(this.indexOf(selectedItem));
5215 }, this).filter(function(unfilteredValue) {
5216 return unfilteredValue != null;
5217 }, this);
5218 }
5219 },
5220 _updateSelected: function() {
5221 if (this.multi) {
5222 this._selectMulti(this.selectedValues);
5223 } else {
5224 this._selectSelected(this.selected);
5225 }
5226 },
5227 _selectMulti: function(values) {
5228 if (values) {
5229 var selectedItems = this._valuesToItems(values);
5230 this._selection.clear(selectedItems);
5231 for (var i = 0; i < selectedItems.length; i++) {
5232 this._selection.setItemSelected(selectedItems[i], true);
5233 }
5234 if (this.fallbackSelection && this.items.length && !this._selection.get(). length) {
5235 var fallback = this._valueToItem(this.fallbackSelection);
5236 if (fallback) {
5237 this.selectedValues = [ this.fallbackSelection ];
5238 }
5239 }
5240 } else {
5241 this._selection.clear();
5242 }
5243 },
5244 _selectionChange: function() {
5245 var s = this._selection.get();
5246 if (this.multi) {
5247 this._setSelectedItems(s);
5248 } else {
5249 this._setSelectedItems([ s ]);
5250 this._setSelectedItem(s);
5251 }
5252 },
5253 _toggleSelected: function(value) {
5254 var i = this.selectedValues.indexOf(value);
5255 var unselected = i < 0;
5256 if (unselected) {
5257 this.push('selectedValues', value);
5258 } else {
5259 this.splice('selectedValues', i, 1);
5260 }
5261 },
5262 _valuesToItems: function(values) {
5263 return values == null ? null : values.map(function(value) {
5264 return this._valueToItem(value);
5265 }, this);
5266 }
5267 };
5268
5269 Polymer.IronMultiSelectableBehavior = [ Polymer.IronSelectableBehavior, Polymer. IronMultiSelectableBehaviorImpl ];
5270
5271 Polymer({
5272 is: 'iron-selector',
5273 behaviors: [ Polymer.IronMultiSelectableBehavior ]
5274 });
5275
5276 // Copyright 2016 The Chromium Authors. All rights reserved. 79 // Copyright 2016 The Chromium Authors. All rights reserved.
5277 // Use of this source code is governed by a BSD-style license that can be 80 // Use of this source code is governed by a BSD-style license that can be
5278 // found in the LICENSE file. 81 // found in the LICENSE file.
5279 Polymer({ 82 Polymer({is:"history-side-bar",behaviors:[Polymer.IronA11yKeysBehavior],properti es:{selectedPage:{type:String,notify:true},showFooter:Boolean,drawer:{type:Boole an,reflectToAttribute:true}},keyBindings:{"space:keydown":"onSpacePressed_"},onS pacePressed_:function(e){e.detail.keyboardEvent.path[0].click()},onSelectorActiv ate_:function(){this.fire("history-close-drawer")},onClearBrowsingDataTap_:funct ion(e){var browserService=md_history.BrowserService.getInstance();browserService .recordAction("InitClearBrowsingData");browserService.openClearBrowsingData();th is.$["cbd-ripple"].upAction();e.preventDefault()},onItemClick_:function(e){e.pre ventDefault()}});
5280 is: 'history-side-bar',
5281 behaviors: [ Polymer.IronA11yKeysBehavior ],
5282 properties: {
5283 selectedPage: {
5284 type: String,
5285 notify: true
5286 },
5287 showFooter: Boolean,
5288 drawer: {
5289 type: Boolean,
5290 reflectToAttribute: true
5291 }
5292 },
5293 keyBindings: {
5294 'space:keydown': 'onSpacePressed_'
5295 },
5296 onSpacePressed_: function(e) {
5297 e.detail.keyboardEvent.path[0].click();
5298 },
5299 onSelectorActivate_: function() {
5300 this.fire('history-close-drawer');
5301 },
5302 onClearBrowsingDataTap_: function(e) {
5303 var browserService = md_history.BrowserService.getInstance();
5304 browserService.recordAction('InitClearBrowsingData');
5305 browserService.openClearBrowsingData();
5306 this.$['cbd-ripple'].upAction();
5307 e.preventDefault();
5308 },
5309 onItemClick_: function(e) {
5310 e.preventDefault();
5311 }
5312 });
5313
5314 // Copyright 2016 The Chromium Authors. All rights reserved. 83 // Copyright 2016 The Chromium Authors. All rights reserved.
5315 // Use of this source code is governed by a BSD-style license that can be 84 // Use of this source code is governed by a BSD-style license that can be
5316 // found in the LICENSE file. 85 // found in the LICENSE file.
5317 cr.define('md_history', function() { 86 cr.define("md_history",function(){var lazyLoadPromise=null;function ensureLazyLo aded(){if(!lazyLoadPromise){lazyLoadPromise=new Promise(function(resolve,reject) {Polymer.Base.importHref("chrome://history/lazy_load.html",resolve,reject,true)} )}return lazyLoadPromise}return{ensureLazyLoaded:ensureLazyLoaded}});Polymer({is :"history-app",behaviors:[Polymer.IronScrollTargetBehavior],properties:{showSide barFooter:Boolean,hasSyncedResults:Boolean,selectedPage_:{type:String,observer:" selectedPageChanged_"},grouped_:{type:Boolean,reflectToAttribute:true},queryStat e_:{type:Object,value:function(){return{incremental:false,querying:true,querying Disabled:false,_range:HistoryRange.ALL_TIME,searchTerm:"",groupedOffset:0,set ra nge(val){this._range=Number(val)},get range(){return this._range}}}},queryResult _:{type:Object,value:function(){return{info:null,results:null,sessionList:null}} },hasDrawer_:Boolean,isUserSignedIn_:{type:Boolean,value:loadTimeData.getBoolean ("isUserSignedIn")},toolbarShadow_:{type:Boolean,reflectToAttribute:true,notify: true}},listeners:{"cr-menu-tap":"onMenuTap_","history-checkbox-select":"checkbox Selected","unselect-all":"unselectAll","delete-selected":"deleteSelected","histo ry-close-drawer":"closeDrawer_","history-view-changed":"historyViewChanged_"},re ady:function(){this.grouped_=loadTimeData.getBoolean("groupByDomain");cr.ui.deco rate("command",cr.ui.Command);document.addEventListener("canExecute",this.onCanE xecute_.bind(this));document.addEventListener("command",this.onCommand_.bind(thi s))},onFirstRender:function(){setTimeout(function(){chrome.send("metricsHandler: recordTime",["History.ResultsRenderedTime",window.performance.now()])});var sear chField=this.$.toolbar.searchField;if(!searchField.narrow){searchField.getSearch Input().focus()}md_history.ensureLazyLoaded()},_scrollHandler:function(){if(this .scrollTarget)this.toolbarShadow_=this.scrollTarget.scrollTop!=0},onMenuTap_:fun ction(){var drawer=this.$$("#drawer");if(drawer)drawer.toggle()},checkboxSelecte d:function(e){var toolbar=this.$.toolbar;toolbar.count=this.$.history.getSelecte dItemCount()},unselectAll:function(){var listContainer=this.$.history;var toolba r=this.$.toolbar;listContainer.unselectAllItems(toolbar.count);toolbar.count=0}, deleteSelected:function(){this.$.history.deleteSelectedWithPrompt()},historyResu lt:function(info,results){this.set("queryState_.querying",false);this.set("query Result_.info",info);this.set("queryResult_.results",results);var listContainer=t his.$["history"];listContainer.historyResult(info,results)},focusToolbarSearchFi eld:function(){this.$.toolbar.showSearchField()},onCanExecute_:function(e){e=e;s witch(e.command.id){case"find-command":e.canExecute=true;break;case"slash-comman d":e.canExecute=!this.$.toolbar.searchField.isSearchFocused();break;case"delete- command":e.canExecute=this.$.toolbar.count>0;break}},onCommand_:function(e){if(e .command.id=="find-command"||e.command.id=="slash-command")this.focusToolbarSear chField();if(e.command.id=="delete-command")this.deleteSelected()},setForeignSes sions:function(sessionList,isTabSyncEnabled){if(!isTabSyncEnabled){var syncedDev iceManagerElem=this.$$("history-synced-device-manager");if(syncedDeviceManagerEl em)syncedDeviceManagerElem.tabSyncDisabled();return}this.set("queryResult_.sessi onList",sessionList)},historyDeleted:function(){this.$.history.historyDeleted()} ,updateSignInState:function(isUserSignedIn){this.isUserSignedIn_=isUserSignedIn} ,syncedTabsSelected_:function(selectedPage){return selectedPage=="syncedTabs"},s houldShowSpinner_:function(querying,incremental,searchTerm){return querying&&!in cremental&&searchTerm!=""},showSyncNotice_:function(hasSyncedResults,selectedPag e){return hasSyncedResults&&selectedPage!="syncedTabs"},selectedPageChanged_:fun ction(){this.unselectAll();this.historyViewChanged_()},historyViewChanged_:funct ion(){requestAnimationFrame(function(){if(!this.$.content.selectedItem)return;th is.scrollTarget=this.$.content.selectedItem.getContentScrollTarget();this._scrol lHandler()}.bind(this));this.recordHistoryPageView_()},getSelectedPage_:function (selectedPage,items){return selectedPage},closeDrawer_:function(){var drawer=thi s.$$("#drawer");if(drawer)drawer.close()},recordHistoryPageView_:function(){var histogramValue=HistoryPageViewHistogram.END;switch(this.selectedPage_){case"sync edTabs":histogramValue=this.isUserSignedIn_?HistoryPageViewHistogram.SYNCED_TABS :HistoryPageViewHistogram.SIGNIN_PROMO;break;default:switch(this.queryState_.ran ge){case HistoryRange.ALL_TIME:histogramValue=HistoryPageViewHistogram.HISTORY;b reak;case HistoryRange.WEEK:histogramValue=HistoryPageViewHistogram.GROUPED_WEEK ;break;case HistoryRange.MONTH:histogramValue=HistoryPageViewHistogram.GROUPED_M ONTH;break}break}md_history.BrowserService.getInstance().recordHistogram("Histor y.HistoryPageView",histogramValue,HistoryPageViewHistogram.END)}});
5318 var lazyLoadPromise = null;
5319 function ensureLazyLoaded() {
5320 if (!lazyLoadPromise) {
5321 lazyLoadPromise = new Promise(function(resolve, reject) {
5322 Polymer.Base.importHref('chrome://history/lazy_load.html', resolve, reje ct, true);
5323 });
5324 }
5325 return lazyLoadPromise;
5326 }
5327 return {
5328 ensureLazyLoaded: ensureLazyLoaded
5329 };
5330 });
5331
5332 Polymer({
5333 is: 'history-app',
5334 behaviors: [ Polymer.IronScrollTargetBehavior ],
5335 properties: {
5336 showSidebarFooter: Boolean,
5337 hasSyncedResults: Boolean,
5338 selectedPage_: {
5339 type: String,
5340 observer: 'selectedPageChanged_'
5341 },
5342 grouped_: {
5343 type: Boolean,
5344 reflectToAttribute: true
5345 },
5346 queryState_: {
5347 type: Object,
5348 value: function() {
5349 return {
5350 incremental: false,
5351 querying: true,
5352 queryingDisabled: false,
5353 _range: HistoryRange.ALL_TIME,
5354 searchTerm: '',
5355 groupedOffset: 0,
5356 set range(val) {
5357 this._range = Number(val);
5358 },
5359 get range() {
5360 return this._range;
5361 }
5362 };
5363 }
5364 },
5365 queryResult_: {
5366 type: Object,
5367 value: function() {
5368 return {
5369 info: null,
5370 results: null,
5371 sessionList: null
5372 };
5373 }
5374 },
5375 hasDrawer_: Boolean,
5376 isUserSignedIn_: {
5377 type: Boolean,
5378 value: loadTimeData.getBoolean('isUserSignedIn')
5379 },
5380 toolbarShadow_: {
5381 type: Boolean,
5382 reflectToAttribute: true,
5383 notify: true
5384 }
5385 },
5386 listeners: {
5387 'cr-menu-tap': 'onMenuTap_',
5388 'history-checkbox-select': 'checkboxSelected',
5389 'unselect-all': 'unselectAll',
5390 'delete-selected': 'deleteSelected',
5391 'history-close-drawer': 'closeDrawer_',
5392 'history-view-changed': 'historyViewChanged_'
5393 },
5394 ready: function() {
5395 this.grouped_ = loadTimeData.getBoolean('groupByDomain');
5396 cr.ui.decorate('command', cr.ui.Command);
5397 document.addEventListener('canExecute', this.onCanExecute_.bind(this));
5398 document.addEventListener('command', this.onCommand_.bind(this));
5399 },
5400 onFirstRender: function() {
5401 setTimeout(function() {
5402 chrome.send('metricsHandler:recordTime', [ 'History.ResultsRenderedTime', window.performance.now() ]);
5403 });
5404 var searchField = this.$.toolbar.searchField;
5405 if (!searchField.narrow) {
5406 searchField.getSearchInput().focus();
5407 }
5408 md_history.ensureLazyLoaded();
5409 },
5410 _scrollHandler: function() {
5411 if (this.scrollTarget) this.toolbarShadow_ = this.scrollTarget.scrollTop != 0;
5412 },
5413 onMenuTap_: function() {
5414 var drawer = this.$$('#drawer');
5415 if (drawer) drawer.toggle();
5416 },
5417 checkboxSelected: function(e) {
5418 var toolbar = this.$.toolbar;
5419 toolbar.count = this.$.history.getSelectedItemCount();
5420 },
5421 unselectAll: function() {
5422 var listContainer = this.$.history;
5423 var toolbar = this.$.toolbar;
5424 listContainer.unselectAllItems(toolbar.count);
5425 toolbar.count = 0;
5426 },
5427 deleteSelected: function() {
5428 this.$.history.deleteSelectedWithPrompt();
5429 },
5430 historyResult: function(info, results) {
5431 this.set('queryState_.querying', false);
5432 this.set('queryResult_.info', info);
5433 this.set('queryResult_.results', results);
5434 var listContainer = this.$['history'];
5435 listContainer.historyResult(info, results);
5436 },
5437 focusToolbarSearchField: function() {
5438 this.$.toolbar.showSearchField();
5439 },
5440 onCanExecute_: function(e) {
5441 e = e;
5442 switch (e.command.id) {
5443 case 'find-command':
5444 e.canExecute = true;
5445 break;
5446
5447 case 'slash-command':
5448 e.canExecute = !this.$.toolbar.searchField.isSearchFocused();
5449 break;
5450
5451 case 'delete-command':
5452 e.canExecute = this.$.toolbar.count > 0;
5453 break;
5454 }
5455 },
5456 onCommand_: function(e) {
5457 if (e.command.id == 'find-command' || e.command.id == 'slash-command') this. focusToolbarSearchField();
5458 if (e.command.id == 'delete-command') this.deleteSelected();
5459 },
5460 setForeignSessions: function(sessionList, isTabSyncEnabled) {
5461 if (!isTabSyncEnabled) {
5462 var syncedDeviceManagerElem = this.$$('history-synced-device-manager');
5463 if (syncedDeviceManagerElem) syncedDeviceManagerElem.tabSyncDisabled();
5464 return;
5465 }
5466 this.set('queryResult_.sessionList', sessionList);
5467 },
5468 historyDeleted: function() {
5469 this.$.history.historyDeleted();
5470 },
5471 updateSignInState: function(isUserSignedIn) {
5472 this.isUserSignedIn_ = isUserSignedIn;
5473 },
5474 syncedTabsSelected_: function(selectedPage) {
5475 return selectedPage == 'syncedTabs';
5476 },
5477 shouldShowSpinner_: function(querying, incremental, searchTerm) {
5478 return querying && !incremental && searchTerm != '';
5479 },
5480 showSyncNotice_: function(hasSyncedResults, selectedPage) {
5481 return hasSyncedResults && selectedPage != 'syncedTabs';
5482 },
5483 selectedPageChanged_: function() {
5484 this.unselectAll();
5485 this.historyViewChanged_();
5486 },
5487 historyViewChanged_: function() {
5488 requestAnimationFrame(function() {
5489 if (!this.$.content.selectedItem) return;
5490 this.scrollTarget = this.$.content.selectedItem.getContentScrollTarget();
5491 this._scrollHandler();
5492 }.bind(this));
5493 this.recordHistoryPageView_();
5494 },
5495 getSelectedPage_: function(selectedPage, items) {
5496 return selectedPage;
5497 },
5498 closeDrawer_: function() {
5499 var drawer = this.$$('#drawer');
5500 if (drawer) drawer.close();
5501 },
5502 recordHistoryPageView_: function() {
5503 var histogramValue = HistoryPageViewHistogram.END;
5504 switch (this.selectedPage_) {
5505 case 'syncedTabs':
5506 histogramValue = this.isUserSignedIn_ ? HistoryPageViewHistogram.SYNCED_TA BS : HistoryPageViewHistogram.SIGNIN_PROMO;
5507 break;
5508
5509 default:
5510 switch (this.queryState_.range) {
5511 case HistoryRange.ALL_TIME:
5512 histogramValue = HistoryPageViewHistogram.HISTORY;
5513 break;
5514
5515 case HistoryRange.WEEK:
5516 histogramValue = HistoryPageViewHistogram.GROUPED_WEEK;
5517 break;
5518
5519 case HistoryRange.MONTH:
5520 histogramValue = HistoryPageViewHistogram.GROUPED_MONTH;
5521 break;
5522 }
5523 break;
5524 }
5525 md_history.BrowserService.getInstance().recordHistogram('History.HistoryPage View', histogramValue, HistoryPageViewHistogram.END);
5526 }
5527 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/md_downloads/vulcanized.html ('k') | chrome/browser/resources/md_history/app.vulcanized.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698