Unreviewed build fix; remove unintentional semicolon.
[WebKit-https.git] / Source / WebCore / Resources / pagepopups / pickerCommon.js
1 "use strict";
2 /*
3  * Copyright (C) 2012 Google Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 /**
27  * @param {!string} id
28  */
29 function $(id) {
30     return document.getElementById(id);
31 }
32
33 /**
34  * @param {!string} tagName
35  * @param {string=} opt_class
36  * @param {string=} opt_text
37  * @return {!Element}
38  */
39 function createElement(tagName, opt_class, opt_text) {
40     var element = document.createElement(tagName);
41     if (opt_class)
42         element.setAttribute("class", opt_class);
43     if (opt_text)
44         element.appendChild(document.createTextNode(opt_text));
45     return element;
46 }
47
48 /**
49  * @constructor
50  * @param {!number|Rectangle|Object} xOrRect
51  * @param {!number} y
52  * @param {!number} width
53  * @param {!number} height
54  */
55 function Rectangle(xOrRect, y, width, height) {
56     if (typeof xOrRect === "object") {
57         y = xOrRect.y;
58         width = xOrRect.width;
59         height = xOrRect.height;
60         xOrRect = xOrRect.x;
61     }
62     this.x = xOrRect;
63     this.y = y;
64     this.width = width;
65     this.height = height;
66 }
67
68 Rectangle.prototype = {
69     get maxX() { return this.x + this.width; },
70     get maxY() { return this.y + this.height; },
71     toString: function() { return "Rectangle(" + this.x + "," + this.y + "," + this.width + "," + this.height + ")"; }
72 };
73
74 /**
75  * @param {!Rectangle} rect1
76  * @param {!Rectangle} rect2
77  * @return {?Rectangle}
78  */
79 Rectangle.intersection = function(rect1, rect2) {
80     var x = Math.max(rect1.x, rect2.x);
81     var maxX = Math.min(rect1.maxX, rect2.maxX);
82     var y = Math.max(rect1.y, rect2.y);
83     var maxY = Math.min(rect1.maxY, rect2.maxY);
84     var width = maxX - x;
85     var height = maxY - y;
86     if (width < 0 || height < 0)
87         return null;
88     return new Rectangle(x, y, width, height);
89 };
90
91 /**
92  * @param {!number} width
93  * @param {!number} height
94  */
95 function resizeWindow(width, height) {
96     setWindowRect(adjustWindowRect(width, height, width, height));
97 }
98
99 /**
100  * @param {!number} width
101  * @param {!number} height
102  * @param {?number} minWidth
103  * @param {?number} minHeight
104  * @return {!Rectangle}
105  */
106 function adjustWindowRect(width, height, minWidth, minHeight) {
107     if (typeof minWidth !== "number")
108         minWidth = 0;
109     if (typeof minHeight !== "number")
110         minHeight = 0;
111
112     var windowRect = new Rectangle(0, 0, width, height);
113
114     if (!global.params.anchorRectInScreen)
115         return windowRect;
116
117     var anchorRect = new Rectangle(global.params.anchorRectInScreen);
118     var availRect = new Rectangle(window.screen.availLeft, window.screen.availTop, window.screen.availWidth, window.screen.availHeight);
119
120     _adjustWindowRectVertically(windowRect, availRect, anchorRect, minHeight);
121     _adjustWindowRectHorizontally(windowRect, availRect, anchorRect, minWidth);
122
123     return windowRect;
124 }
125
126 function _adjustWindowRectVertically(windowRect, availRect, anchorRect, minHeight) {
127     var availableSpaceAbove = anchorRect.y - availRect.y;
128     availableSpaceAbove = Math.max(0, Math.min(availRect.height, availableSpaceAbove));
129
130     var availableSpaceBelow = availRect.maxY - anchorRect.maxY;
131     availableSpaceBelow = Math.max(0, Math.min(availRect.height, availableSpaceBelow));
132
133     if (windowRect.height > availableSpaceBelow && availableSpaceBelow < availableSpaceAbove) {
134         windowRect.height = Math.min(windowRect.height, availableSpaceAbove);
135         windowRect.height = Math.max(windowRect.height, minHeight);
136         windowRect.y = anchorRect.y - windowRect.height;
137     } else {
138         windowRect.height = Math.min(windowRect.height, availableSpaceBelow);
139         windowRect.height = Math.max(windowRect.height, minHeight);
140         windowRect.y = anchorRect.maxY;
141     }
142     windowRect.y = Math.min(windowRect.y, availRect.maxY - windowRect.height);
143     windowRect.y = Math.max(windowRect.y, availRect.y);
144 }
145
146 function _adjustWindowRectHorizontally(windowRect, availRect, anchorRect, minWidth) {
147     windowRect.width = Math.min(windowRect.width, availRect.width);
148     windowRect.width = Math.max(windowRect.width, minWidth);
149     windowRect.x = anchorRect.x;
150     if (global.params.isRTL)
151         windowRect.x += anchorRect.width - windowRect.width;
152     windowRect.x = Math.min(windowRect.x, availRect.maxX - windowRect.width);
153     windowRect.x = Math.max(windowRect.x, availRect.x);
154 }
155
156 /**
157  * @param {!Rectangle} rect
158  */
159 function setWindowRect(rect) {
160     if (window.frameElement) {
161         window.frameElement.style.width = rect.width + "px";
162         window.frameElement.style.height = rect.height + "px";
163     } else {
164         if (isWindowHidden()) {
165             window.moveTo(rect.x - window.screen.availLeft, rect.y - window.screen.availTop);
166             window.resizeTo(rect.width, rect.height);
167         } else {
168             window.resizeTo(rect.width, rect.height);
169             window.moveTo(rect.x - window.screen.availLeft, rect.y - window.screen.availTop);
170         }
171     }
172 }
173
174 function hideWindow() {
175     resizeWindow(1, 1);
176 }
177
178 /**
179  * @return {!boolean}
180  */
181 function isWindowHidden() {
182     return window.innerWidth === 1 && window.innerHeight === 1;
183 }
184
185 window.addEventListener("resize", function() {
186     if (isWindowHidden())
187         window.dispatchEvent(new CustomEvent("didHide"));
188     else
189         window.dispatchEvent(new CustomEvent("didOpenPicker"));
190 }, false);
191
192 /**
193  * @return {!number}
194  */
195 function getScrollbarWidth() {
196     if (typeof window.scrollbarWidth === "undefined") {
197         var scrollDiv = document.createElement("div");
198         scrollDiv.style.opacity = "0";
199         scrollDiv.style.overflow = "scroll";
200         scrollDiv.style.width = "50px";
201         scrollDiv.style.height = "50px";
202         document.body.appendChild(scrollDiv);
203         window.scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
204         scrollDiv.parentNode.removeChild(scrollDiv);
205     }
206     return window.scrollbarWidth;
207 }
208
209 /**
210  * @param {!string} className
211  * @return {?Element}
212  */
213 function enclosingNodeOrSelfWithClass(selfNode, className)
214 {
215     for (var node = selfNode; node && node !== selfNode.ownerDocument; node = node.parentNode) {
216         if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains(className))
217             return node;
218     }
219     return null;
220 };
221
222 /**
223  * @constructor
224  * @param {!Element} element
225  * @param {!Object} config
226  */
227 function Picker(element, config) {
228     this._element = element;
229     this._config = config;
230 }
231
232 /**
233  * @enum {number}
234  */
235 Picker.Actions = {
236     SetValue: 0,
237     Cancel: -1,
238     ChooseOtherColor: -2
239 };
240
241 /**
242  * @param {!string} value
243  */
244 Picker.prototype.submitValue = function(value) {
245     window.pagePopupController.setValue(value);
246     window.pagePopupController.closePopup();
247 }
248
249 Picker.prototype.handleCancel = function() {
250     window.pagePopupController.closePopup();
251 }
252
253 Picker.prototype.chooseOtherColor = function() {
254     window.pagePopupController.setValueAndClosePopup(Picker.Actions.ChooseOtherColor, "");
255 }
256
257 Picker.prototype.cleanup = function() {};