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