blob: 7034329f830f75eee4a5ea3fd370993373e1f43c [file] [log] [blame]
"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 - window.screen.availLeft, rect.y - window.screen.availTop);
window.resizeTo(rect.width, rect.height);
} else {
window.resizeTo(rect.width, rect.height);
window.moveTo(rect.x - window.screen.availLeft, rect.y - window.screen.availTop);
}
}
}
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() {};