Home | History | Annotate | Download | only in debugger
      1 <!DOCTYPE html>
      2 <html>
      3   <!--
      4   Copyright 2013 Google Inc.
      5 
      6   Use of this source code is governed by a BSD-style license that can be
      7   found in the LICENSE file.
      8   -->
      9 <head>
     10   <title>Skia Debugger</title>
     11   <link rel="stylesheet" type="text/css" href="debugger.css"/>
     12   <script type="text/javascript">
     13     "use strict";
     14 
     15     var skia_module = null;  // Global application object.
     16     var display_right_panel = null;
     17     var display_bottom_row = null;
     18     var overview_text = "";
     19     var details_text = "Default details text.";
     20     var command_list = [];
     21     var command_types = {};
     22     var no_filter_text = "--Filter By Available Commands--";
     23 
     24     function openFileDialog() {
     25       var event = document.createEvent("MouseEvents");
     26       event.initEvent("click", true, false);
     27       document.getElementById("file_open").dispatchEvent(event);
     28     }
     29 
     30     function updateOverviewDetails() {
     31       var radio_buttons = document.getElementsByName("overviewdetails_radio");
     32       for (var i = 0; i < radio_buttons.length; ++i) {
     33         if (radio_buttons[i].checked) {
     34           if (radio_buttons[i].value == "details") {
     35             document.getElementById("overviewdetails").innerHTML = details_text;
     36           } else {
     37             document.getElementById("overviewdetails").innerHTML = overview_text;
     38           }
     39           return;
     40         }
     41       }
     42       // If no radio button is checked, check the "overview" button.
     43       for (var i = 0; i < radio_buttons.length; ++i) {
     44         if (radio_buttons[i].value == "overview") {
     45           radio_buttons[i].checked = true;
     46           document.getElementById("overviewdetails").innerHTML = overview_text;
     47           return;
     48         }
     49       }
     50     }
     51 
     52     function makeIndentString(indent_amt) {
     53       var indent_str = "";
     54       for (var i = 0; i < indent_amt; ++i) {
     55         indent_str += "--";
     56       }
     57       return indent_str;
     58     }
     59 
     60     function updateCommandList(filter) {
     61       var command_list_display = document.getElementById("command_list");
     62       command_list_display.options.length = 0;
     63       var indent = 0;
     64       var indent_str = "";
     65       for (var i = 0; i < command_list.length; ++i) {
     66         if (command_list[i] == "Restore") {
     67           indent--;
     68           indent_str = makeIndentString(indent);
     69         }
     70         if (!filter || filter == no_filter_text || command_list[i] == filter) {
     71           command_list_display.options.add(new Option(indent_str + command_list[i], i));
     72         }
     73         if (command_list[i] == "Save" || command_list[i] == "Save Layer") {
     74           indent++;
     75           indent_str = makeIndentString(indent);
     76         }
     77       }
     78       command_list_display.selectedIndex = command_list_display.length - 1;
     79 
     80       // TODO(borenet): Should the SKP re-draw when the command list is updated?
     81       //commandSelected();
     82     }
     83 
     84     function updateFilterList() {
     85       var filter_list_display = document.getElementById("command_filter");
     86       filter_list_display.options.length = 0;
     87       filter_list_display.options.add(new Option(no_filter_text, no_filter_text));
     88       for (var command_type in command_types) {
     89         if (command_types.hasOwnProperty(command_type)) {
     90           filter_list_display.options.add(new Option(command_type, command_type));
     91         }
     92       }
     93     }
     94 
     95     function openFile(event) {
     96       document.getElementById("overviewdetails").innerHTML = "";
     97       var files = event.target.files;
     98       if (files.length != 1) {
     99         return;
    100       }
    101       var file = files[0];
    102       var reader = new FileReader();
    103       reader.onload = (function(theFile) {
    104         return function(e) {
    105           var data_prefix = "data:;base64,";
    106           skia_module.postMessage("LoadSKP" + e.target.result.slice(data_prefix.length));
    107         };
    108       })(file);
    109       reader.readAsDataURL(file);
    110     }
    111 
    112     function toggleInspector() {
    113       var right_panel = document.getElementById("right_panel");
    114       var bottom_row = document.getElementById("bottom_row");
    115       if (right_panel.style.display == display_right_panel) {
    116         right_panel.style.display = "none";
    117         bottom_row.style.display = "none";
    118       } else {
    119         right_panel.style.display = display_right_panel;
    120         bottom_row.style.display = display_bottom_row;
    121       }
    122     }
    123 
    124     function onLoad() {
    125       document.getElementById("file_open").addEventListener("change", openFile, false);
    126       var right_panel = document.getElementById("right_panel");
    127       var bottom_row = document.getElementById("bottom_row");
    128       display_right_panel = right_panel.style.display;
    129       display_bottom_row = bottom_row.style.display;
    130       updateOverviewDetails();
    131       updateFilterList();
    132     }
    133 
    134     // When the module loads, begin running the application.
    135     function moduleDidLoad() {
    136       skia_module = document.getElementById("skia_nacl");
    137       sendMsg("init");
    138     }
    139 
    140     function handleMessage(message_event) {
    141       var cmd_skdebugf = "SkDebugf:";
    142       var cmd_clear_commands = "ClearCommands";
    143       var cmd_add_command = "AddCommand:";
    144       var cmd_update_commands = "UpdateCommands";
    145       var cmd_set_overview = "SetOverview:";
    146       var cmd_add_filter_option = "AddFilterOption";
    147       if (message_event.data.indexOf(cmd_skdebugf) == 0) {
    148         var msg_contents = message_event.data.slice(cmd_skdebugf.length)
    149         console.log("Skia: " + msg_contents);
    150       } else if (message_event.data.indexOf(cmd_clear_commands) == 0) {
    151         command_list = [];
    152         command_types = {};
    153         updateCommandList();
    154         updateFilterList();
    155       } else if (message_event.data.indexOf(cmd_add_command) == 0) {
    156         var command = message_event.data.slice(cmd_add_command.length);
    157         command_list.push(command);
    158         if (command_types[command] == undefined) {
    159           command_types[command] = 1;
    160         } else {
    161           command_types[command]++;
    162         }
    163       } else if (message_event.data.indexOf(cmd_update_commands) == 0) {
    164         updateCommandList();
    165         updateFilterList();
    166       } else if (message_event.data.indexOf(cmd_set_overview) == 0) {
    167         overview_text = message_event.data.slice(cmd_set_overview.length);
    168         document.getElementById("overview_radio").checked = true;
    169         updateOverviewDetails();
    170       } else {
    171         alert(message_event.data);
    172       }
    173     }
    174 
    175     // Send a message to the plugin.
    176     function sendMsg(msg) {
    177       if (skia_module) {
    178         //console.log("Sending msg:" + msg);
    179         skia_module.postMessage(msg);
    180       } else {
    181         alert("The Skia module has not properly loaded...");
    182       }
    183     }
    184 
    185     function commandSelected() {
    186       var command_list = document.getElementById("command_list");
    187       var selected_index = command_list.options[command_list.selectedIndex].value;
    188       if (selected_index >= 0) {
    189         sendMsg("CommandSelected:" + selected_index);
    190       }
    191     }
    192 
    193     function rewind() {
    194       command_list.selectedIndex = 0;
    195       sendMsg("Rewind");
    196     }
    197 
    198     function stepBack() {
    199       if (command_list.selectedIndex > 0) {
    200         command_list.selectedIndex = command_list.selectedIndex - 1;
    201       }
    202       sendMsg("StepBack");
    203     }
    204 
    205     function pause() {
    206       sendMsg("Pause");
    207     }
    208 
    209     function stepForward() {
    210       if (command_list.selectedIndex < command_list.length - 1) {
    211         command_list.selectedIndex = command_list.selectedIndex + 1;
    212       }
    213       sendMsg("StepForward");
    214     }
    215 
    216     function play() {
    217       command_list.selectedIndex = command_list.length - 1;
    218       sendMsg("Play");
    219     }
    220   </script>
    221 </head>
    222 <body onLoad="javascript:onLoad()">
    223 <div id="content" class="row-set">
    224   <div id="menu" class="row">
    225     <ul id="menu-bar" class="dropdown-menu">
    226       <li><a href="#">File</a>
    227         <ul>
    228           <li><a href="#" onClick="javascript:openFileDialog()">Open</a></li>
    229           <li><a href="#">Save</a></li>
    230           <li><a href="#">Save As</a></li>
    231           <li><a href="#">Exit</a></li>
    232         </ul>
    233       </li>
    234       <li><a href="#">Edit</a>
    235         <ul>
    236           <li><a href="#">Delete Command</a></li>
    237           <li><a href="#">Clear Deletes</a></li>
    238           <li><a href="#">Set Breakpoint</a></li>
    239           <li><a href="#">Clear Breakpoints</a></li>
    240         </ul>
    241       </li>
    242       <li><a href="#">View</a>
    243         <ul>
    244           <li><a href="#">Breakpoints</a></li>
    245           <li><a href="#">Deleted Commands</a></li>
    246           <li><a href="#">Zoom In</a></li>
    247           <li><a href="#">Zoom Out</a></li>
    248         </ul>
    249       </li>
    250       <li><a href="#">Navigate</a>
    251         <ul>
    252           <li><a href="#" onClick="javascript:rewind()">Rewind</a></li>
    253           <li><a href="#" onClick="javascript:stepBack()">Step Back</a></li>
    254           <li><a href="#" onClick="javascript:stepForward()">Step Forward</a></li>
    255           <li><a href="#" onClick="javascript:play()">Play</a></li>
    256           <li><a href="#" onClick="javascript:pause()">Pause</a></li>
    257           <li><a href="#">Go to Line...</a></li>
    258         </ul>
    259       </li>
    260       <li><a href="#">Window</a>
    261         <ul>
    262           <li><a href="#">Inspector</a></li>
    263           <li><a href="#">Directory</a></li>
    264         </ul>
    265       </li>
    266     </ul>
    267   </div>
    268   <div id="buttons" class="row">
    269     <div class="column-set">
    270       <div class="column">
    271         <button onClick="javascript:rewind()"><img src="icons/rewind.png"/><br/>Rewind</button>
    272         <button onClick="javascript:stepBack()"><img src="icons/previous.png"/><br/>Step Back</button>
    273         <button onClick="javascript:pause()"><img src="icons/pause.png"/><br/>Pause</button>
    274         <button onClick="javascript:stepForward()"><img src="icons/next.png"/><br/>Step Forward</button>
    275         <button onClick="javascript:play()"><img src="icons/play.png"/><br/>Play</button>
    276       </div>
    277       <div class="column">
    278         <button onClick="javascript:toggleInspector()"><img src="icons/inspector.png"/><br/>Inspector</button>
    279       </div>
    280       <div class="column">
    281         <button><img src="icons/profile.png"/><br/>Profile</button>
    282       </div>
    283       <div class="column" style="text-align:right; vertical-align:middle;">
    284         <select id="command_filter" onChange="javascript:updateCommandList(this.options[this.selectedIndex].value)"></select>
    285         <button onClick="javascript:updateCommandList()"><img src="icons/reload.png" /><br/>Clear Filter</button>
    286       </div>
    287     </div>
    288   </div>
    289   <div class="row">
    290     <div class="column-set">
    291       <div id="left_column" class="column">
    292         <div class="row-set">
    293           <div id="command_list_div" class="row">
    294             <form id="command_list_form">
    295               <select id="command_list" size="2" onChange="javascript:commandSelected()">
    296                 <option value="-1">Commands go here...</option>
    297               </select>
    298             </form>
    299           </div>
    300         </div>
    301       </div>
    302       <div id="right_column" class="row-set">
    303         <div id="top_row" class="row">
    304           <div id="display_pane" class="column">
    305             <div id="listener" style="width:100%; height:100%;">
    306               <script type="text/javascript">
    307                 var listener = document.getElementById('listener');
    308                 listener.addEventListener('load', moduleDidLoad, true);
    309                 listener.addEventListener('message', handleMessage, true);
    310               </script>
    311               <embed name="nacl_module"
    312                  id="skia_nacl"
    313                  src="debugger.nmf"
    314                  type="application/x-nacl"
    315                  width="100%"
    316                  height="100%"
    317                  style="width:100%, height:100%;"/>
    318             </div>
    319           </div>
    320           <div id="right_panel" class="column">
    321             <div class="thin_outline">
    322               <div id="visibility_filter" class="settings_block">
    323                 Visibility Filter<br/>
    324                 <div class="thin_outline">
    325                   <form id="visibility_filter_form">
    326                     <input type="radio" name="visibility_filter_radio" value="on">On<br/>
    327                     <input type="radio" name="visibility_filter_radio" value="off" checked>Off
    328                   </form>
    329                 </div>
    330               </div>
    331               <div id="command_scrolling" class="settings_block">
    332                 Command Scrolling Preferences<br/>
    333                 <div class="thin_outline">
    334                   <div class="row-set">
    335                     <div class="row">
    336                       <div class="column-set">
    337                         <div class="column">
    338                           Current Command:
    339                         </div>
    340                         <div class="column" style="text-align:right; width:35%;">
    341                           <input type="text" style="width:100%;"/>
    342                         </div>
    343                       </div>
    344                     </div>
    345                     <div class="row">
    346                       <div class="column-set">
    347                         <div class="column">
    348                           Command HitBox:
    349                         </div>
    350                         <div class="column" style="text-align:right; width:35%;">
    351                           <input type="text" style="width:100%;"/>
    352                         </div>
    353                       </div>
    354                     </div>
    355                   </div>
    356                 </div>
    357               </div>
    358               <div id="render_targets" class="settings_block">
    359                 Render Targets<br/>
    360                 <div class="thin_outline">
    361                   <form id="render_targets_form">
    362                     <div class="row-set">
    363                       <div class="row">
    364                         <div class="column-set">
    365                           <div class="column">Raster:</div>
    366                           <div class="column" style="text-align:right;">
    367                             <input type="checkbox" name="render_targets_checkbox" value="raster" checked/>
    368                           </div>
    369                         </div>
    370                       </div>
    371                       <div class="row">
    372                         <div class="column-set">
    373                           <div class="column" style="padding-left:30px;">Overdraw Viz:</div>
    374                           <div class="column" style="text-align:right;">
    375                             <input type="checkbox" name="render_targets_checkbox" value="overdraw"/>
    376                           </div>
    377                         </div>
    378                       </div>
    379                       <div class="row">
    380                         <div class="column-set">
    381                           <div class="column">OpenGL</div>
    382                           <div class="column" style="text-align:right;">
    383                             <input type="checkbox" name="render_targets_checkbox" value="opengl"/>
    384                           </div>
    385                         </div>
    386                       </div>
    387                     </div>
    388                   </form>
    389                 </div>
    390               </div>
    391               <div id="zoom_level" class="settings_block">
    392                 <div class="thin_outline">
    393                   <div class="row-set">
    394                     <div class="row">
    395                       <div class="column-set">
    396                         <div class="column">
    397                           Zoom Level:
    398                         </div>
    399                         <div class="column" style="text-align:right; width:35%;">
    400                           <input type="text" style="width:100%;"/>
    401                         </div>
    402                       </div>
    403                     </div>
    404                   </div>
    405                 </div>
    406               </div>
    407             </div>
    408             <div id="small_window_wrapper" class="settings_block">
    409               <div class="thin_outline" style="padding:0px;">
    410                 <div id="small_window">
    411                 </div>
    412               </div>
    413             </div>
    414           </div>
    415         </div>
    416         <div id="bottom_row" class="row">
    417           <div id="tabview" class="column">
    418             <div class="row-set">
    419               <div class="row" style="height:5px; overflow:auto;">
    420                 <form id="overviewdetails_form">
    421                   <input type="radio" name="overviewdetails_radio" onChange="javascript:updateOverviewDetails()" id="overview_radio" value="overview" checked>Overview
    422                   <input type="radio" name="overviewdetails_radio" onChange="javascript:updateOverviewDetails()" id="details_radio" value="details">Details
    423                 </form>
    424               </div>
    425               <div class="row">
    426                 <div id="overviewdetails"></div>
    427               </div>
    428             </div>
    429           </div>
    430           <div id="matrixclip" class="column">
    431             Current Matrix
    432             <table>
    433               <tr>
    434                 <td><input type="text" id="matrix00" class="matrix" /></td>
    435                 <td><input type="text" id="matrix01" class="matrix" /></td>
    436                 <td><input type="text" id="matrix02" class="matrix" /></td>
    437               </tr>
    438               <tr>
    439                 <td><input type="text" id="matrix10" class="matrix" /></td>
    440                 <td><input type="text" id="matrix11" class="matrix" /></td>
    441                 <td><input type="text" id="matrix12" class="matrix" /></td>
    442               </tr>
    443               <tr>
    444                 <td><input type="text" id="matrix20" class="matrix" /></td>
    445                 <td><input type="text" id="matrix21" class="matrix" /></td>
    446                 <td><input type="text" id="matrix22" class="matrix" /></td>
    447               </tr>
    448             </table>
    449             Current Clip
    450             <table>
    451               <tr>
    452                 <td><input type="text" id="clip00" class="matrix" /></td>
    453                 <td><input type="text" id="clip01" class="matrix" /></td>
    454               </tr>
    455               <tr>
    456                 <td><input type="text" id="clip10" class="matrix" /></td>
    457                 <td><input type="text" id="clip11" class="matrix" /></td>
    458               </tr>
    459             </table>
    460           </div>
    461         </div>
    462       </div>
    463     </div>
    464   </div>
    465 </div>
    466 <input type="file" id="file_open" style="display:none;"/>
    467 </body>
    468 </html>
    469