api_util.js revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright 2014 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 5/** 6 * @fileoverview Shared util methods between api.js and api_implementation.js 7 * for doing common tasks such as passing node references between page script 8 * and ChromeVox. 9 */ 10 11if (typeof(goog) != 'undefined' && goog.provide){ 12 goog.provide('cvox.ApiUtil'); 13} 14 15 16if (!window['cvox']) { 17 window['cvox'] = {}; 18} 19 20/** 21 * @constructor 22 */ 23cvox.ApiUtils = function() { 24}; 25 26/** 27 * The next id to use for the cvoxid attribute that we add to elements 28 * in order to be able to find them from the content script. 29 * @type {number} 30 */ 31cvox.ApiUtils.nextCvoxId_ = 1; 32 33/** 34 * Makes a serializable reference to a node. 35 * If the node or its parent has an ID, reference it directly. Otherwise, 36 * add a temporary cvoxid attribute. This has a corresponding method in 37 * api_implementation.js to decode this and return a node. 38 * @param {Node} targetNode The node to reference. 39 * @return {Object} A serializable node reference. 40 */ 41cvox.ApiUtils.makeNodeReference = function(targetNode) { 42 if (targetNode.id && document.getElementById(targetNode.id) == targetNode) { 43 return {'id': targetNode.id}; 44 } else if (targetNode instanceof HTMLElement) { 45 var cvoxid = cvox.ApiUtils.nextCvoxId_; 46 targetNode.setAttribute('cvoxid', cvoxid); 47 cvox.ApiUtils.nextCvoxId_ = (cvox.ApiUtils.nextCvoxId_ + 1) % 100; 48 return {'cvoxid': cvoxid}; 49 } else if (targetNode.parentElement) { 50 var parent = targetNode.parentElement; 51 var childIndex = -1; 52 for (var i = 0; i < parent.childNodes.length; i++) { 53 if (parent.childNodes[i] == targetNode) { 54 childIndex = i; 55 break; 56 } 57 } 58 if (childIndex >= 0) { 59 var cvoxid = cvox.ApiUtils.nextCvoxId_; 60 parent.setAttribute('cvoxid', cvoxid); 61 cvox.ApiUtils.nextCvoxId_ = (cvox.ApiUtils.nextCvoxId_ + 1) % 100; 62 return {'cvoxid': cvoxid, 'childIndex': childIndex}; 63 } 64 } 65 throw 'Cannot reference node: ' + targetNode; 66}; 67 68/** 69 * Retrieves a node from its serializable node reference. 70 * 71 * @param {Object} nodeRef A serializable reference to a node. 72 * @return {Node} The node on the page that this object refers to. 73 */ 74cvox.ApiUtils.getNodeFromRef = function(nodeRef) { 75 if (nodeRef['id']) { 76 return document.getElementById(nodeRef['id']); 77 } else if (nodeRef['cvoxid']) { 78 var selector = '*[cvoxid="' + nodeRef['cvoxid'] + '"]'; 79 var element = document.querySelector(selector); 80 if (element && element.removeAttribute) { 81 element.removeAttribute('cvoxid'); 82 } 83 if (nodeRef['childIndex'] != null) { 84 return element.childNodes[nodeRef['childIndex']]; 85 } else { 86 return element; 87 } 88 } 89 throw 'Bad node reference: ' + cvox.ChromeVoxJSON.stringify(nodeRef); 90}; 91