• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2013 Google Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/**
16 * @fileoverview Shared util methods between api.js and api_implementation.js
17 * for doing common tasks such as passing node references between page script
18 * and ChromeVox.
19 *
20 * @author clchen@google.com (Charles L. Chen)
21 */
22
23if (typeof(goog) != 'undefined' && goog.provide){
24  goog.provide('cvox.ApiUtil');
25}
26
27
28if (!window['cvox']) {
29   window['cvox'] = {};
30}
31
32/**
33 * @constructor
34 */
35cvox.ApiUtils = function() {
36};
37
38/**
39 * The next id to use for the cvoxid attribute that we add to elements
40 * in order to be able to find them from the content script.
41 * @type {number}
42 */
43cvox.ApiUtils.nextCvoxId_ = 1;
44
45/**
46 * Makes a serializable reference to a node.
47 * If the node or its parent has an ID, reference it directly. Otherwise,
48 * add a temporary cvoxid attribute. This has a corresponding method in
49 * api_implementation.js to decode this and return a node.
50 * @param {Node} targetNode The node to reference.
51 * @return {Object} A serializable node reference.
52 */
53cvox.ApiUtils.makeNodeReference = function(targetNode) {
54  if (targetNode.id && document.getElementById(targetNode.id) == targetNode) {
55    return {'id': targetNode.id};
56  } else if (targetNode instanceof HTMLElement) {
57    var cvoxid = cvox.ApiUtils.nextCvoxId_;
58    targetNode.setAttribute('cvoxid', cvoxid);
59    cvox.ApiUtils.nextCvoxId_ = (cvox.ApiUtils.nextCvoxId_ + 1) % 100;
60    return {'cvoxid': cvoxid};
61  } else if (targetNode.parentElement) {
62    var parent = targetNode.parentElement;
63    var childIndex = -1;
64    for (var i = 0; i < parent.childNodes.length; i++) {
65      if (parent.childNodes[i] == targetNode) {
66        childIndex = i;
67        break;
68      }
69    }
70    if (childIndex >= 0) {
71      var cvoxid = cvox.ApiUtils.nextCvoxId_;
72      parent.setAttribute('cvoxid', cvoxid);
73      cvox.ApiUtils.nextCvoxId_ = (cvox.ApiUtils.nextCvoxId_ + 1) % 100;
74      return {'cvoxid': cvoxid, 'childIndex': childIndex};
75    }
76  }
77  throw 'Cannot reference node: ' + targetNode;
78};
79
80/**
81 * Retrieves a node from its serializable node reference.
82 *
83 * @param {Object} nodeRef A serializable reference to a node.
84 * @return {Node} The node on the page that this object refers to.
85 */
86cvox.ApiUtils.getNodeFromRef = function(nodeRef) {
87  if (nodeRef['id']) {
88    return document.getElementById(nodeRef['id']);
89  } else if (nodeRef['cvoxid']) {
90    var selector = '*[cvoxid="' + nodeRef['cvoxid'] + '"]';
91    var element = document.querySelector(selector);
92    if (element && element.removeAttribute) {
93      element.removeAttribute('cvoxid');
94    }
95    if (nodeRef['childIndex'] != null) {
96      return element.childNodes[nodeRef['childIndex']];
97    } else {
98      return element;
99    }
100  }
101  throw 'Bad node reference: ' + cvox.ChromeVoxJSON.stringify(nodeRef);
102};
103