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