| OLD | NEW |
| 1 "use strict"; | 1 "use strict"; |
| 2 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 2 // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| 3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
| 4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
| 5 | 5 |
| 6 var global = { | 6 var global = { |
| 7 argumentsReceived: false, | 7 argumentsReceived: false, |
| 8 params: null, | 8 params: null, |
| 9 picker: null | 9 picker: null |
| 10 }; | 10 }; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 * @constructor | 38 * @constructor |
| 39 * @param {!Element} element | 39 * @param {!Element} element |
| 40 * @param {!Object} config | 40 * @param {!Object} config |
| 41 */ | 41 */ |
| 42 function ListPicker(element, config) { | 42 function ListPicker(element, config) { |
| 43 Picker.call(this, element, config); | 43 Picker.call(this, element, config); |
| 44 window.pagePopupController.selectFontsFromOwnerDocument(document); | 44 window.pagePopupController.selectFontsFromOwnerDocument(document); |
| 45 this._selectElement = createElement("select"); | 45 this._selectElement = createElement("select"); |
| 46 this._selectElement.size = 20; | 46 this._selectElement.size = 20; |
| 47 this._element.appendChild(this._selectElement); | 47 this._element.appendChild(this._selectElement); |
| 48 this._delayedChildrenConfig = null; |
| 49 this._delayedChildrenConfigIndex = 0; |
| 48 this._layout(); | 50 this._layout(); |
| 49 this._selectElement.addEventListener("mouseup", this._handleMouseUp.bind(thi
s), false); | 51 this._selectElement.addEventListener("mouseup", this._handleMouseUp.bind(thi
s), false); |
| 50 this._selectElement.addEventListener("touchstart", this._handleTouchStart.bi
nd(this), false); | 52 this._selectElement.addEventListener("touchstart", this._handleTouchStart.bi
nd(this), false); |
| 51 this._selectElement.addEventListener("keydown", this._handleKeyDown.bind(thi
s), false); | 53 this._selectElement.addEventListener("keydown", this._handleKeyDown.bind(thi
s), false); |
| 52 this._selectElement.addEventListener("change", this._handleChange.bind(this)
, false); | 54 this._selectElement.addEventListener("change", this._handleChange.bind(this)
, false); |
| 53 window.addEventListener("message", this._handleWindowMessage.bind(this), fal
se); | 55 window.addEventListener("message", this._handleWindowMessage.bind(this), fal
se); |
| 54 window.addEventListener("mousemove", this._handleWindowMouseMove.bind(this),
false); | 56 window.addEventListener("mousemove", this._handleWindowMouseMove.bind(this),
false); |
| 55 window.addEventListener("touchmove", this._handleWindowTouchMove.bind(this),
false); | 57 window.addEventListener("touchmove", this._handleWindowTouchMove.bind(this),
false); |
| 56 window.addEventListener("touchend", this._handleWindowTouchEnd.bind(this), f
alse); | 58 window.addEventListener("touchend", this._handleWindowTouchEnd.bind(this), f
alse); |
| 57 this.lastMousePositionX = Infinity; | 59 this.lastMousePositionX = Infinity; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 optionUnderMouse = elementUnderMouse && elementUnderMouse.closest("optio
n"); | 247 optionUnderMouse = elementUnderMouse && elementUnderMouse.closest("optio
n"); |
| 246 } | 248 } |
| 247 if (optionUnderMouse) | 249 if (optionUnderMouse) |
| 248 optionUnderMouse.selected = true; | 250 optionUnderMouse.selected = true; |
| 249 else | 251 else |
| 250 this._selectElement.value = oldValue; | 252 this._selectElement.value = oldValue; |
| 251 this._selectElement.scrollTop = scrollPosition; | 253 this._selectElement.scrollTop = scrollPosition; |
| 252 this.dispatchEvent("didUpdate"); | 254 this.dispatchEvent("didUpdate"); |
| 253 }; | 255 }; |
| 254 | 256 |
| 257 ListPicker.DelayedLayoutThreshold = 1000; |
| 258 |
| 255 /** | 259 /** |
| 256 * @param {!Element} parent Select element or optgroup element. | 260 * @param {!Element} parent Select element or optgroup element. |
| 257 * @param {!Object} config | 261 * @param {!Object} config |
| 258 */ | 262 */ |
| 259 ListPicker.prototype._updateChildren = function(parent, config) { | 263 ListPicker.prototype._updateChildren = function(parent, config) { |
| 260 var outOfDateIndex = 0; | 264 var outOfDateIndex = 0; |
| 261 var fragment = null; | 265 var fragment = null; |
| 262 var inGroup = parent.tagName === "OPTGROUP"; | 266 var inGroup = parent.tagName === "OPTGROUP"; |
| 263 for (var i = 0; i < config.children.length; ++i) { | 267 var lastListIndex = -1; |
| 268 var limit = Math.max(this._config.selectedIndex, ListPicker.DelayedLayoutThr
eshold); |
| 269 var i; |
| 270 for (i = 0; i < config.children.length; ++i) { |
| 271 if (!inGroup && lastListIndex >= limit) |
| 272 break; |
| 264 var childConfig = config.children[i]; | 273 var childConfig = config.children[i]; |
| 265 var item = this._findReusableItem(parent, childConfig, outOfDateIndex) |
| this._createItemElement(childConfig); | 274 var item = this._findReusableItem(parent, childConfig, outOfDateIndex) |
| this._createItemElement(childConfig); |
| 266 this._configureItem(item, childConfig, inGroup); | 275 this._configureItem(item, childConfig, inGroup); |
| 276 lastListIndex = item.value ? Number(item.value) : -1; |
| 267 if (outOfDateIndex < parent.children.length) { | 277 if (outOfDateIndex < parent.children.length) { |
| 268 parent.insertBefore(item, parent.children[outOfDateIndex]); | 278 parent.insertBefore(item, parent.children[outOfDateIndex]); |
| 269 } else { | 279 } else { |
| 270 if (!fragment) | 280 if (!fragment) |
| 271 fragment = document.createDocumentFragment(); | 281 fragment = document.createDocumentFragment(); |
| 272 fragment.appendChild(item); | 282 fragment.appendChild(item); |
| 273 } | 283 } |
| 274 outOfDateIndex++; | 284 outOfDateIndex++; |
| 275 } | 285 } |
| 276 if (fragment) { | 286 if (fragment) { |
| 277 parent.appendChild(fragment); | 287 parent.appendChild(fragment); |
| 288 } else { |
| 289 var unused = parent.children.length - outOfDateIndex; |
| 290 for (var j = 0; j < unused; j++) { |
| 291 parent.removeChild(parent.lastElementChild); |
| 292 } |
| 293 } |
| 294 if (i < config.children.length) { |
| 295 // We don't bind |config.children| and |i| to _updateChildrenLater |
| 296 // because config.children can get invalid before _updateChildrenLater |
| 297 // is called. |
| 298 this._delayedChildrenConfig = config.children; |
| 299 this._delayedChildrenConfigIndex = i; |
| 300 requestAnimationFrame(this._updateChildrenLater.bind(this)); |
| 301 } |
| 302 }; |
| 303 |
| 304 ListPicker.prototype._updateChildrenLater = function(timeStamp) { |
| 305 if (!this._delayedChildrenConfig) |
| 278 return; | 306 return; |
| 307 var startIndex = this._delayedChildrenConfigIndex; |
| 308 for (; this._delayedChildrenConfigIndex < this._delayedChildrenConfig.length
&& this._delayedChildrenConfigIndex - startIndex < ListPicker.DelayedLayoutThre
shold; ++this._delayedChildrenConfigIndex) { |
| 309 var childConfig = this._delayedChildrenConfig[this._delayedChildrenConfi
gIndex]; |
| 310 var item = this._createItemElement(childConfig); |
| 311 this._configureItem(item, childConfig, false); |
| 312 this._selectElement.appendChild(item); |
| 279 } | 313 } |
| 280 var unused = parent.children.length - outOfDateIndex; | 314 if (this._delayedChildrenConfigIndex < this._delayedChildrenConfig.length) |
| 281 for (var i = 0; i < unused; i++) { | 315 requestAnimationFrame(this._updateChildrenLater.bind(this)); |
| 282 parent.removeChild(parent.lastElementChild); | 316 else |
| 283 } | 317 this._delayedChildrenConfig = null; |
| 318 this._selectElement.classList.add("wrap"); |
| 284 }; | 319 }; |
| 285 | 320 |
| 286 ListPicker.prototype._findReusableItem = function(parent, config, startIndex) { | 321 ListPicker.prototype._findReusableItem = function(parent, config, startIndex) { |
| 287 if (startIndex >= parent.children.length) | 322 if (startIndex >= parent.children.length) |
| 288 return null; | 323 return null; |
| 289 var tagName = "OPTION"; | 324 var tagName = "OPTION"; |
| 290 if (config.type === "optgroup") | 325 if (config.type === "optgroup") |
| 291 tagName = "OPTGROUP"; | 326 tagName = "OPTGROUP"; |
| 292 else if (config.type === "separator") | 327 else if (config.type === "separator") |
| 293 tagName = "HR"; | 328 tagName = "HR"; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 } | 404 } |
| 370 this._applyItemStyle(element, config.style); | 405 this._applyItemStyle(element, config.style); |
| 371 }; | 406 }; |
| 372 | 407 |
| 373 if (window.dialogArguments) { | 408 if (window.dialogArguments) { |
| 374 initialize(dialogArguments); | 409 initialize(dialogArguments); |
| 375 } else { | 410 } else { |
| 376 window.addEventListener("message", handleMessage, false); | 411 window.addEventListener("message", handleMessage, false); |
| 377 window.setTimeout(handleArgumentsTimeout, 1000); | 412 window.setTimeout(handleArgumentsTimeout, 1000); |
| 378 } | 413 } |
| OLD | NEW |