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 */ 34WebInspector.ShortcutsScreen = function() 35{ 36 this._sections = /** @type {Object.<string, !WebInspector.ShortcutsSection>} */ ({}); 37} 38 39WebInspector.ShortcutsScreen.prototype = { 40 /** 41 * @param {string} name 42 * @return {!WebInspector.ShortcutsSection} 43 */ 44 section: function(name) 45 { 46 var section = this._sections[name]; 47 if (!section) 48 this._sections[name] = section = new WebInspector.ShortcutsSection(name); 49 return section; 50 }, 51 52 /** 53 * @return {!WebInspector.View} 54 */ 55 createShortcutsTabView: function() 56 { 57 var orderedSections = []; 58 for (var section in this._sections) 59 orderedSections.push(this._sections[section]); 60 function compareSections(a, b) 61 { 62 return a.order - b.order; 63 } 64 orderedSections.sort(compareSections); 65 66 var view = new WebInspector.View(); 67 68 view.element.className = "settings-tab-container"; 69 view.element.createChild("header").createChild("h3").appendChild(document.createTextNode(WebInspector.UIString("Shortcuts"))); 70 var container = view.element.createChild("div", "help-container-wrapper").createChild("div"); 71 container.className = "help-content help-container"; 72 for (var i = 0; i < orderedSections.length; ++i) 73 orderedSections[i].renderSection(container); 74 75 return view; 76 } 77} 78 79/** 80 * We cannot initialize it here as localized strings are not loaded yet. 81 * @type {?WebInspector.ShortcutsScreen} 82 */ 83WebInspector.shortcutsScreen = null; 84 85/** 86 * @constructor 87 * @param {string} name 88 */ 89WebInspector.ShortcutsSection = function(name) 90{ 91 this.name = name; 92 this._lines = /** @type {!Array.<{key: !Node, text: string}>} */ ([]); 93 this.order = ++WebInspector.ShortcutsSection._sequenceNumber; 94}; 95 96WebInspector.ShortcutsSection._sequenceNumber = 0; 97 98WebInspector.ShortcutsSection.prototype = { 99 /** 100 * @param {!WebInspector.KeyboardShortcut.Descriptor} key 101 * @param {string} description 102 */ 103 addKey: function(key, description) 104 { 105 this._addLine(this._renderKey(key), description); 106 }, 107 108 /** 109 * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys 110 * @param {string} description 111 */ 112 addRelatedKeys: function(keys, description) 113 { 114 this._addLine(this._renderSequence(keys, "/"), description); 115 }, 116 117 /** 118 * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} keys 119 * @param {string} description 120 */ 121 addAlternateKeys: function(keys, description) 122 { 123 this._addLine(this._renderSequence(keys, WebInspector.UIString("or")), description); 124 }, 125 126 /** 127 * @param {!Node} keyElement 128 * @param {string} description 129 */ 130 _addLine: function(keyElement, description) 131 { 132 this._lines.push({ key: keyElement, text: description }) 133 }, 134 135 /** 136 * @param {!Element} container 137 */ 138 renderSection: function(container) 139 { 140 var parent = container.createChild("div", "help-block"); 141 142 var headLine = parent.createChild("div", "help-line"); 143 headLine.createChild("div", "help-key-cell"); 144 headLine.createChild("div", "help-section-title help-cell").textContent = this.name; 145 146 for (var i = 0; i < this._lines.length; ++i) { 147 var line = parent.createChild("div", "help-line"); 148 var keyCell = line.createChild("div", "help-key-cell"); 149 keyCell.appendChild(this._lines[i].key); 150 keyCell.appendChild(this._createSpan("help-key-delimiter", ":")); 151 line.createChild("div", "help-cell").textContent = this._lines[i].text; 152 } 153 }, 154 155 /** 156 * @param {!Array.<!WebInspector.KeyboardShortcut.Descriptor>} sequence 157 * @param {string} delimiter 158 * @return {!Node} 159 */ 160 _renderSequence: function(sequence, delimiter) 161 { 162 var delimiterSpan = this._createSpan("help-key-delimiter", delimiter); 163 return this._joinNodes(sequence.map(this._renderKey.bind(this)), delimiterSpan); 164 }, 165 166 /** 167 * @param {!WebInspector.KeyboardShortcut.Descriptor} key 168 * @return {!Node} 169 */ 170 _renderKey: function(key) 171 { 172 var keyName = key.name; 173 var plus = this._createSpan("help-combine-keys", "+"); 174 return this._joinNodes(keyName.split(" + ").map(this._createSpan.bind(this, "help-key monospace")), plus); 175 }, 176 177 /** 178 * @param {string} className 179 * @param {string} textContent 180 * @return {!Element} 181 */ 182 _createSpan: function(className, textContent) 183 { 184 var node = document.createElement("span"); 185 node.className = className; 186 node.textContent = textContent; 187 return node; 188 }, 189 190 /** 191 * @param {!Array.<!Element>} nodes 192 * @param {!Element} delimiter 193 * @return {!Node} 194 */ 195 _joinNodes: function(nodes, delimiter) 196 { 197 var result = document.createDocumentFragment(); 198 for (var i = 0; i < nodes.length; ++i) { 199 if (i > 0) 200 result.appendChild(delimiter.cloneNode(true)); 201 result.appendChild(nodes[i]); 202 } 203 return result; 204 } 205} 206