1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5cr.define('accessibility', function() { 6 'use strict'; 7 8 function requestData() { 9 var xhr = new XMLHttpRequest(); 10 xhr.open('GET', 'targets-data.json', false); 11 xhr.send(null); 12 if (xhr.status === 200) { 13 console.log(xhr.responseText); 14 return JSON.parse(xhr.responseText); 15 } 16 return []; 17 } 18 19 // TODO(aboxhall): add a mechanism to request individual and global a11y 20 // mode, xhr them on toggle... or just re-requestData and be smarter about 21 // ID-ing rows? 22 23 function toggleAccessibility(data, element) { 24 chrome.send('toggleAccessibility', 25 [String(data.processId), String(data.routeId)]); 26 var a11y_was_on = (element.textContent.match(/on/) != null); 27 element.textContent = ' accessibility ' + (a11y_was_on ? ' off' : ' on'); 28 var row = element.parentElement; 29 if (a11y_was_on) { 30 while (row.lastChild != element) 31 row.removeChild(row.lastChild); 32 } else { 33 row.appendChild(document.createTextNode(' | ')); 34 row.appendChild(createShowAccessibilityTreeElement(data, row, false)); 35 } 36 } 37 38 function requestAccessibilityTree(data, element) { 39 chrome.send('requestAccessibilityTree', 40 [String(data.processId), String(data.routeId)]); 41 } 42 43 function toggleGlobalAccessibility() { 44 chrome.send('toggleGlobalAccessibility'); 45 document.location.reload(); // FIXME see TODO above 46 } 47 48 function initialize() { 49 console.log('initialize'); 50 var data = requestData(); 51 52 addGlobalAccessibilityModeToggle(data['global_a11y_mode']); 53 54 $('pages').textContent = ''; 55 56 var list = data['list']; 57 for (var i = 0; i < list.length; i++) { 58 addToPagesList(list[i]); 59 } 60 } 61 62 function addGlobalAccessibilityModeToggle(global_a11y_mode) { 63 $('toggle_global').textContent = (global_a11y_mode == 0 ? 'off' : 'on'); 64 $('toggle_global').addEventListener('click', 65 toggleGlobalAccessibility); 66 } 67 68 function addToPagesList(data) { 69 // TODO: iterate through data and pages rows instead 70 var id = data['processId'] + '.' + data['routeId']; 71 var row = document.createElement('div'); 72 row.className = 'row'; 73 row.id = id; 74 formatRow(row, data); 75 76 row.processId = data.processId; 77 row.routeId = data.routeId; 78 79 var list = $('pages'); 80 list.appendChild(row); 81 } 82 83 function formatRow(row, data) { 84 if (!('url' in data)) { 85 if ('error' in data) { 86 row.appendChild(createErrorMessageElement(data, row)); 87 return; 88 } 89 } 90 var properties = ['favicon_url', 'name', 'url']; 91 for (var j = 0; j < properties.length; j++) 92 row.appendChild(formatValue(data, properties[j])); 93 94 row.appendChild(createToggleAccessibilityElement(data)); 95 if (data['a11y_mode'] != 0) { 96 row.appendChild(document.createTextNode(' | ')); 97 if ('tree' in data) { 98 row.appendChild(createShowAccessibilityTreeElement(data, row, true)); 99 row.appendChild(document.createTextNode(' | ')); 100 row.appendChild(createHideAccessibilityTreeElement(row.id)); 101 row.appendChild(createAccessibilityTreeElement(data)); 102 } 103 else { 104 row.appendChild(createShowAccessibilityTreeElement(data, row, false)); 105 if ('error' in data) 106 row.appendChild(createErrorMessageElement(data, row)); 107 } 108 } 109 } 110 111 function formatValue(data, property) { 112 var value = data[property]; 113 114 if (property == 'favicon_url') { 115 var faviconElement = document.createElement('img'); 116 if (value) 117 faviconElement.src = value; 118 faviconElement.alt = ""; 119 return faviconElement; 120 } 121 122 var text = value ? String(value) : ''; 123 if (text.length > 100) 124 text = text.substring(0, 100) + '\u2026'; // ellipsis 125 126 var span = document.createElement('span'); 127 span.textContent = ' ' + text + ' '; 128 span.className = property; 129 return span; 130 } 131 132 function createToggleAccessibilityElement(data) { 133 var link = document.createElement('a'); 134 link.setAttribute('href', '#'); 135 var a11y_mode = data['a11y_mode']; 136 link.textContent = 'accessibility ' + (a11y_mode == 0 ? 'off' : 'on'); 137 link.addEventListener('click', 138 toggleAccessibility.bind(this, data, link)); 139 return link; 140 } 141 142 function createShowAccessibilityTreeElement(data, row, opt_refresh) { 143 var link = document.createElement('a'); 144 link.setAttribute('href', '#'); 145 if (opt_refresh) 146 link.textContent = 'refresh accessibility tree'; 147 else 148 link.textContent = 'show accessibility tree'; 149 link.id = row.id + ':showTree'; 150 link.addEventListener('click', 151 requestAccessibilityTree.bind(this, data, link)); 152 return link; 153 } 154 155 function createHideAccessibilityTreeElement(id) { 156 var link = document.createElement('a'); 157 link.setAttribute('href', '#'); 158 link.textContent = 'hide accessibility tree'; 159 link.addEventListener('click', 160 function() { 161 $(id + ':showTree').textContent = 'show accessibility tree'; 162 var existingTreeElements = $(id).getElementsByTagName('pre'); 163 for (var i = 0; i < existingTreeElements.length; i++) 164 $(id).removeChild(existingTreeElements[i]); 165 var row = $(id); 166 while (row.lastChild != $(id + ':showTree')) 167 row.removeChild(row.lastChild); 168 }); 169 return link; 170 } 171 172 function createErrorMessageElement(data) { 173 var errorMessageElement = document.createElement('div'); 174 var errorMessage = data.error; 175 errorMessageElement.innerHTML = errorMessage + ' '; 176 var closeLink = document.createElement('a'); 177 closeLink.href='#'; 178 closeLink.textContent = '[close]'; 179 closeLink.addEventListener('click', function() { 180 var parentElement = errorMessageElement.parentElement; 181 parentElement.removeChild(errorMessageElement); 182 if (parentElement.childElementCount == 0) 183 parentElement.parentElement.removeChild(parentElement); 184 }); 185 errorMessageElement.appendChild(closeLink); 186 return errorMessageElement; 187 } 188 189 function showTree(data) { 190 var id = data.processId + '.' + data.routeId; 191 var row = $(id); 192 if (!row) 193 return; 194 195 row.textContent = ''; 196 formatRow(row, data); 197 } 198 199 function createAccessibilityTreeElement(data) { 200 var treeElement = document.createElement('pre'); 201 var tree = data.tree; 202 treeElement.textContent = tree; 203 return treeElement; 204 } 205 206 return { 207 initialize: initialize, 208 showTree: showTree 209 }; 210}); 211 212document.addEventListener('DOMContentLoaded', accessibility.initialize); 213