tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebCore / inspector / front-end / ShortcutsScreen.js
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 /**
32  * @constructor
33  * @extends {WebInspector.HelpScreen}
34  */
35 WebInspector.ShortcutsScreen = function()
36 {
37     WebInspector.HelpScreen.call(this, WebInspector.UIString("Keyboard Shortcuts"));
38     this._sections = {};
39     this._tableReady = false;
40 }
41
42 WebInspector.ShortcutsScreen.prototype = {
43     section: function(name)
44     {
45         var section = this._sections[name];
46         if (!section)
47             this._sections[name] = section = new WebInspector.ShortcutsSection(name);
48         return section;
49     },
50
51     show: function(onHide)
52     {
53         this._buildTable(this.contentElement, 2);
54         WebInspector.HelpScreen.prototype.show.call(this, onHide);
55     },
56
57     _buildTable: function(parent, nColumns)
58     {
59         if (this._tableReady)
60             return;
61         this._tableReady = true;
62
63         var height = 0;
64         var orderedSections = [];
65         for (var section in this._sections) {
66             height += this._sections[section]._height;
67             orderedSections.push(this._sections[section])
68         }
69         function compareSections(a, b)
70         {
71             return a.order - b.order;
72         }
73         orderedSections = orderedSections.sort(compareSections);
74
75         const wrapAfter = height / nColumns;
76         var table = document.createElement("table");
77         table.className = "help-table";
78         var row = table.createChild("tr");
79
80         // This manual layout ugliness should be gone once WebKit implements
81         // pagination hints for CSS columns (break-inside etc).
82         for (var section = 0; section < orderedSections.length;) {
83             var td = row.createChild("td");
84             td.style.width = (100 / nColumns) + "%";
85             var column = td.createChild("table");
86             for (var columnHeight = 0;
87                 columnHeight < wrapAfter && section < orderedSections.length;
88                 columnHeight += orderedSections[section]._height, section++) {
89                 orderedSections[section].renderSection(column);
90             }
91         }
92         parent.appendChild(table);
93     }
94 }
95
96 WebInspector.ShortcutsScreen.prototype.__proto__ = WebInspector.HelpScreen.prototype;
97
98 /**
99  * We cannot initialize it here as localized strings are not loaded yet.
100  * @type {?WebInspector.ShortcutsScreen}
101  */
102 WebInspector.shortcutsScreen = null;
103
104 /**
105  * @constructor
106  */
107 WebInspector.ShortcutsSection = function(name)
108 {
109     this.name = name;
110     this._lines = [];
111     this.order = ++WebInspector.ShortcutsSection._sequenceNumber;
112 };
113
114 WebInspector.ShortcutsSection._sequenceNumber = 0;
115
116 WebInspector.ShortcutsSection.prototype = {
117     addKey: function(key, description)
118     {
119         this._addLine(this._renderKey(key), description);
120     },
121
122     addRelatedKeys: function(keys, description)
123     {
124         this._addLine(this._renderSequence(keys, "/"), description);
125     },
126
127     addAlternateKeys: function(keys, description)
128     {
129         this._addLine(this._renderSequence(keys, WebInspector.UIString("or")), description);
130     },
131
132     _addLine: function(keyElement, description)
133     {
134         this._lines.push({ key: keyElement, text: description })
135     },
136
137     renderSection: function(parent)
138     {
139         this._renderHeader(parent);
140
141         for (var line = 0; line < this._lines.length; ++line) {
142             var tr = parent.createChild("tr");
143             var td = tr.createChild("td", "help-key-cell");
144             td.appendChild(this._lines[line].key);
145             td.appendChild(document.createTextNode(" : "));
146             tr.createChild("td").textContent = this._lines[line].text;
147         }
148     },
149
150     _renderHeader: function(parent)
151     {
152         var trHead = parent.createChild("tr");
153
154         trHead.createChild("th");
155         trHead.createChild("th").textContent = this.name;
156     },
157
158     _renderSequence: function(sequence, delimiter)
159     {
160         var delimiterSpan = this._createSpan("help-key-delimiter", delimiter);
161         return this._joinNodes(sequence.map(this._renderKey.bind(this)), delimiterSpan);
162     },
163
164     _renderKey: function(key)
165     {
166         var plus = this._createSpan("help-combine-keys", "+");
167         return this._joinNodes(key.split(" + ").map(this._createSpan.bind(this, "help-key monospace")), plus);
168     },
169
170     get _height()
171     {
172         return this._lines.length + 2; // add some space for header
173     },
174
175     _createSpan: function(className, textContent)
176     {
177         var node = document.createElement("span");
178         node.className = className;
179         node.textContent = textContent;
180         return node;
181     },
182
183     _joinNodes: function(nodes, delimiter)
184     {
185         var result = document.createDocumentFragment();
186         for (var i = 0; i < nodes.length; ++i) {
187             if (i > 0)
188                 result.appendChild(delimiter.cloneNode(true));
189             result.appendChild(nodes[i]);
190         }
191         return result;
192     }
193 }