• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 + '&nbsp;';
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