"use strict"; /* * Copyright (C) 2012 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * @param {!string} id */ function $(id) { return document.getElementById(id); } /** * @param {!string} tagName * @param {string=} opt_class * @param {string=} opt_text * @return {!Element} */ function createElement(tagName, opt_class, opt_text) { var element = document.createElement(tagName); if (opt_class) element.setAttribute("class", opt_class); if (opt_text) element.appendChild(document.createTextNode(opt_text)); return element; } /** * @constructor * @param {!number|Rectangle|Object} xOrRect * @param {!number} y * @param {!number} width * @param {!number} height */ function Rectangle(xOrRect, y, width, height) { if (typeof xOrRect === "object") { y = xOrRect.y; width = xOrRect.width; height = xOrRect.height; xOrRect = xOrRect.x; } this.x = xOrRect; this.y = y; this.width = width; this.height = height; } Rectangle.prototype = { get maxX() { return this.x + this.width; }, get maxY() { return this.y + this.height; }, toString: function() { return "Rectangle(" + this.x + "," + this.y + "," + this.width + "," + this.height + ")"; } }; /** * @param {!Rectangle} rect1 * @param {!Rectangle} rect2 * @return {?Rectangle} */ Rectangle.intersection = function(rect1, rect2) { var x = Math.max(rect1.x, rect2.x); var maxX = Math.min(rect1.maxX, rect2.maxX); var y = Math.max(rect1.y, rect2.y); var maxY = Math.min(rect1.maxY, rect2.maxY); var width = maxX - x; var height = maxY - y; if (width < 0 || height < 0) return null; return new Rectangle(x, y, width, height); }; /** * @param {!number} width * @param {!number} height */ function resizeWindow(width, height) { setWindowRect(adjustWindowRect(width, height, width, height)); } /** * @param {!number} width * @param {!number} height * @param {?number} minWidth * @param {?number} minHeight * @return {!Rectangle} */ function adjustWindowRect(width, height, minWidth, minHeight) { if (typeof minWidth !== "number") minWidth = 0; if (typeof minHeight !== "number") minHeight = 0; var windowRect = new Rectangle(0, 0, width, height); if (!global.params.anchorRectInScreen) return windowRect; var anchorRect = new Rectangle(global.params.anchorRectInScreen); var availRect = new Rectangle(window.screen.availLeft, window.screen.availTop, window.screen.availWidth, window.screen.availHeight); _adjustWindowRectVertically(windowRect, availRect, anchorRect, minHeight); _adjustWindowRectHorizontally(windowRect, availRect, anchorRect, minWidth); return windowRect; } function _adjustWindowRectVertically(windowRect, availRect, anchorRect, minHeight) { var availableSpaceAbove = anchorRect.y - availRect.y; availableSpaceAbove = Math.max(0, Math.min(availRect.height, availableSpaceAbove)); var availableSpaceBelow = availRect.maxY - anchorRect.maxY; availableSpaceBelow = Math.max(0, Math.min(availRect.height, availableSpaceBelow)); if (windowRect.height > availableSpaceBelow && availableSpaceBelow < availableSpaceAbove) { windowRect.height = Math.min(windowRect.height, availableSpaceAbove); windowRect.height = Math.max(windowRect.height, minHeight); windowRect.y = anchorRect.y - windowRect.height; } else { windowRect.height = Math.min(windowRect.height, availableSpaceBelow); windowRect.height = Math.max(windowRect.height, minHeight); windowRect.y = anchorRect.maxY; } windowRect.y = Math.min(windowRect.y, availRect.maxY - windowRect.height); windowRect.y = Math.max(windowRect.y, availRect.y); } function _adjustWindowRectHorizontally(windowRect, availRect, anchorRect, minWidth) { windowRect.width = Math.min(windowRect.width, availRect.width); windowRect.width = Math.max(windowRect.width, minWidth); windowRect.x = anchorRect.x; if (global.params.isRTL) windowRect.x += anchorRect.width - windowRect.width; windowRect.x = Math.min(windowRect.x, availRect.maxX - windowRect.width); windowRect.x = Math.max(windowRect.x, availRect.x); } /** * @param {!Rectangle} rect */ function setWindowRect(rect) { if (window.frameElement) { window.frameElement.style.width = rect.width + "px"; window.frameElement.style.height = rect.height + "px"; } else { if (isWindowHidden()) { window.moveTo(rect.x, rect.y); window.resizeTo(rect.width, rect.height); } else { window.resizeTo(rect.width, rect.height); window.moveTo(rect.x, rect.y); } } } function hideWindow() { resizeWindow(1, 1); } /** * @return {!boolean} */ function isWindowHidden() { return window.innerWidth === 1 && window.innerHeight === 1; } window.addEventListener("resize", function() { if (isWindowHidden()) window.dispatchEvent(new CustomEvent("didHide")); else window.dispatchEvent(new CustomEvent("didOpenPicker")); }, false); /** * @return {!number} */ function getScrollbarWidth() { if (typeof window.scrollbarWidth === "undefined") { var scrollDiv = document.createElement("div"); scrollDiv.style.opacity = "0"; scrollDiv.style.overflow = "scroll"; scrollDiv.style.width = "50px"; scrollDiv.style.height = "50px"; document.body.appendChild(scrollDiv); window.scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth; scrollDiv.parentNode.removeChild(scrollDiv); } return window.scrollbarWidth; } /** * @param {!string} className * @return {?Element} */ function enclosingNodeOrSelfWithClass(selfNode, className) { for (var node = selfNode; node && node !== selfNode.ownerDocument; node = node.parentNode) { if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains(className)) return node; } return null; }; /** * @constructor * @param {!Element} element * @param {!Object} config */ function Picker(element, config) { this._element = element; this._config = config; } /** * @enum {number} */ Picker.Actions = { SetValue: 0, Cancel: -1, ChooseOtherColor: -2 }; /** * @param {!string} value */ Picker.prototype.submitValue = function(value) { window.pagePopupController.setValue(value); window.pagePopupController.closePopup(); } Picker.prototype.handleCancel = function() { window.pagePopupController.closePopup(); } Picker.prototype.chooseOtherColor = function() { window.pagePopupController.setValueAndClosePopup(Picker.Actions.ChooseOtherColor, ""); } Picker.prototype.cleanup = function() {};