initial import
[vuplus_webkit] / 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 WebInspector.ShortcutsScreen = function()
32 {
33     this._sections = {};
34 }
35
36 WebInspector.ShortcutsScreen.prototype = {
37     section: function(name)
38     {
39         var section = this._sections[name];
40         if (!section)
41             this._sections[name] = section = new WebInspector.ShortcutsSection(name);
42         return section;
43     },
44
45     show: function()
46     {
47         if (!this._helpScreen) {
48             this._helpScreen = new WebInspector.HelpScreen(WebInspector.UIString("Keyboard Shortcuts"));
49             this._buildTable(this._helpScreen.contentElement, 2);
50         }
51         this._helpScreen.show();
52     },
53
54     hide: function()
55     {
56         if (this._helpScreen)
57             this._helpScreen.hide();
58     },
59
60     _buildTable: function(parent, nColumns)
61     {
62         var height = 0;
63         var orderedSections = [];
64         for (var section in this._sections) {
65             height += this._sections[section]._height;
66             orderedSections.push(this._sections[section])
67         }
68         function compareSections(a, b)
69         {
70             return a.order - b.order;
71         }
72         orderedSections = orderedSections.sort(compareSections);
73
74         const wrapAfter = height / nColumns;
75         var table = document.createElement("table");
76         table.className = "help-table";
77         var row = table.createChild("tr");
78
79         // This manual layout ugliness should be gone once WebKit implements
80         // pagination hints for CSS columns (break-inside etc).
81         for (var section = 0; section < orderedSections.length;) {
82             var td = row.createChild("td");
83             td.style.width = (100 / nColumns) + "%";
84             var column = td.createChild("table");
85             for (var columnHeight = 0;
86                 columnHeight < wrapAfter && section < orderedSections.length;
87                 columnHeight += orderedSections[section]._height, section++) {
88                 orderedSections[section].renderSection(column);
89             }
90         }
91         parent.appendChild(table);
92     }
93 };
94
95 WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen();
96
97 WebInspector.ShortcutsSection = function(name)
98 {
99     this.name = name;
100     this._lines = [];
101     this.order = ++WebInspector.ShortcutsSection._sequenceNumber;
102 };
103
104 WebInspector.ShortcutsSection._sequenceNumber = 0;
105
106 WebInspector.ShortcutsSection.prototype = {
107     addKey: function(key, description)
108     {
109         this.addLine(this._renderKey(key), description);
110     },
111
112     addRelatedKeys: function(keys, description)
113     {
114         this.addLine(this._renderSequence(keys,"/"), description);
115     },
116
117     addAlternateKeys: function(keys, description)
118     {
119         this.addLine(this._renderSequence(keys,WebInspector.UIString("or")), description);
120     },
121
122     addLine: function(htmlKey, description)
123     {
124         this._lines.push({ key: htmlKey, text: description })
125     },
126
127     renderSection: function(parent)
128     {
129         this._renderHeader(parent);
130
131         for (var line = 0; line < this._lines.length; ++line) {
132             var tr = parent.createChild("tr");
133             tr.createChild("td", "help-key-cell").innerHTML = this._lines[line].key + " : ";
134             tr.createChild("td").textContent = this._lines[line].text;
135         }
136     },
137
138     _renderHeader: function(parent)
139     {
140         var trHead = parent.createChild("tr");
141
142         trHead.createChild("th");
143         trHead.createChild("th").textContent = this.name;
144     },
145
146     _renderSequence: function(sequence, delimiter)
147     {
148         var delimiterHtml = '<span class="help-key-delimiter">' + delimiter.escapeHTML() + '</span>'
149         return sequence.map(this._renderKey).join(delimiterHtml);
150     },
151
152     _renderKey: function(key)
153     {
154         function renderLabel(label)
155         {
156             return '<span class="help-key monospace">' + label.escapeHTML() + '</span>';
157         }
158         return key.split(" + ").map(renderLabel).join('<span class="help-combine-keys">+</span>');
159     },
160
161     get _height()
162     {
163         return this._lines.length + 2; // add some space for header
164     }
165 };