[Qt] css2.1/t1* tests needs rebaseline after new testfonts
[WebKit-https.git] / Source / WebCore / Resources / colorSuggestionPicker.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 var global = {
27     argumentsReceived: false,
28     scrollbarWidth: null
29 };
30
31 /**
32  * @param {!string} id
33  */
34 function $(id) {
35     return document.getElementById(id);
36 }
37
38 function bind(func, context) {
39     return function() {
40         return func.apply(context, arguments);
41     };
42 }
43
44 function getScrollbarWidth() {
45     if (gloabal.scrollbarWidth === null) {
46         var scrollDiv = document.createElement("div");
47         scrollDiv.style.opacity = "0";
48         scrollDiv.style.overflow = "scroll";
49         scrollDiv.style.width = "50px";
50         scrollDiv.style.height = "50px";
51         document.body.appendChild(scrollDiv);
52         gloabal.scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
53         scrollDiv.parentNode.removeChild(scrollDiv);
54     }
55     return gloabal.scrollbarWidth;
56 }
57
58 /**
59  * @param {!string} tagName
60  * @param {string=} opt_class
61  * @param {string=} opt_text
62  * @return {!Element}
63  */
64 function createElement(tagName, opt_class, opt_text) {
65     var element = document.createElement(tagName);
66     if (opt_class)
67         element.setAttribute("class", opt_class);
68     if (opt_text)
69         element.appendChild(document.createTextNode(opt_text));
70     return element;
71 }
72
73 /**
74  * @param {Event} event
75  */
76 function handleMessage(event) {
77     initialize(JSON.parse(event.data));
78     global.argumentsReceived = true;
79 }
80
81 /**
82  * @param {!Object} args
83  */
84 function initialize(args) {
85     var main = $("main");
86     main.innerHTML = "";
87     var errorString = validateArguments(args);
88     if (errorString)
89         main.textContent = "Internal error: " + errorString;
90     else
91         new ColorPicker(main, args);
92 }
93
94 // The DefaultColorPalette is used when the list of values are empty. 
95 var DefaultColorPalette = ["#000000", "#404040", "#808080", "#c0c0c0",
96     "#ffffff", "#980000", "#ff0000", "#ff9900", "#ffff00", "#00ff00", "#00ffff",
97     "#4a86e8", "#0000ff", "#9900ff", "#ff00ff"];
98
99 function handleArgumentsTimeout() {
100     if (global.argumentsReceived)
101         return;
102     var args = {
103         values : DefaultColorPalette,
104         otherColorLabel: "Other..."
105     };
106     initialize(args);
107 }
108
109 /**
110  * @param {!Object} args
111  * @return {?string} An error message, or null if the argument has no errors.
112  */
113 function validateArguments(args) {
114     if (!args.values)
115         return "No values.";
116     if (!args.otherColorLabel)
117         return "No otherColorLabel.";
118     return null;
119 }
120
121 var Actions = {
122     ChooseOtherColor: -2,
123     Cancel: -1,
124     SetValue: 0
125 };
126
127 /**
128  * @param {string} value
129  */
130 function submitValue(value) {
131     window.pagePopupController.setValueAndClosePopup(Actions.SetValue, value);
132 }
133
134 function handleCancel() {
135     window.pagePopupController.setValueAndClosePopup(Actions.Cancel, "");
136 }
137
138 function chooseOtherColor() {
139     window.pagePopupController.setValueAndClosePopup(Actions.ChooseOtherColor, "");
140 }
141
142 function ColorPicker(element, config) {
143     this._element = element;
144     this._config = config;
145     if (this._config.values.length === 0)
146         this._config.values = DefaultColorPalette;
147     this._layout();
148 }
149
150 var SwatchBorderBoxWidth = 24; // keep in sync with CSS
151 var SwatchBorderBoxHeight = 24; // keep in sync with CSS
152 var SwatchesPerRow = 5;
153 var SwatchesMaxRow = 4;
154
155 ColorPicker.prototype._layout = function() {
156     var container = createElement("div", "color-swatch-container");
157     container.addEventListener("click", bind(this._handleSwatchClick, this), false);
158     for (var i = 0; i < this._config.values.length; ++i) {
159         var swatch = createElement("div", "color-swatch");
160         swatch.dataset.value = this._config.values[i];
161         swatch.title = this._config.values[i];
162         swatch.style.backgroundColor = this._config.values[i];
163         container.appendChild(swatch);
164     }
165     var containerWidth = SwatchBorderBoxWidth * SwatchesPerRow;
166     if (this._config.values.length > SwatchesPerRow * SwatchesMaxRow)
167         containerWidth += getScrollbarWidth();
168     container.style.width = containerWidth + "px";
169     container.style.maxHeight = (SwatchBorderBoxHeight * SwatchesMaxRow) + "px";
170     this._element.appendChild(container);
171     var otherButton = createElement("button", "other-color", this._config.otherColorLabel);
172     otherButton.addEventListener("click", chooseOtherColor, false);
173     this._element.appendChild(otherButton);
174     if (window.frameElement) {
175         window.frameElement.style.width = this._element.offsetWidth + "px";
176         window.frameElement.style.height = this._element.offsetHeight + "px";
177     } else {
178         window.resizeTo(this._element.offsetWidth, this._element.offsetHeight);
179     }
180 };
181
182 ColorPicker.prototype._handleSwatchClick = function(event) {
183     if (event.target.classList.contains("color-swatch"))
184         submitValue(event.target.dataset.value);
185 };
186
187 if (window.dialogArguments) {
188     initialize(dialogArguments);
189 } else {
190     window.addEventListener("message", handleMessage, false);
191     window.setTimeout(handleArgumentsTimeout, 1000);
192 }