| // Copyright 2013 Google Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| /** |
| * @fileoverview Shared util methods between api.js and api_implementation.js |
| * for doing common tasks such as passing node references between page script |
| * and ChromeVox. |
| * |
| * @author clchen@google.com (Charles L. Chen) |
| */ |
| |
| if (typeof(goog) != 'undefined' && goog.provide){ |
| goog.provide('cvox.ApiUtil'); |
| } |
| |
| |
| if (!window['cvox']) { |
| window['cvox'] = {}; |
| } |
| |
| /** |
| * @constructor |
| */ |
| cvox.ApiUtils = function() { |
| }; |
| |
| /** |
| * The next id to use for the cvoxid attribute that we add to elements |
| * in order to be able to find them from the content script. |
| * @type {number} |
| */ |
| cvox.ApiUtils.nextCvoxId_ = 1; |
| |
| /** |
| * Makes a serializable reference to a node. |
| * If the node or its parent has an ID, reference it directly. Otherwise, |
| * add a temporary cvoxid attribute. This has a corresponding method in |
| * api_implementation.js to decode this and return a node. |
| * @param {Node} targetNode The node to reference. |
| * @return {Object} A serializable node reference. |
| */ |
| cvox.ApiUtils.makeNodeReference = function(targetNode) { |
| if (targetNode.id && document.getElementById(targetNode.id) == targetNode) { |
| return {'id': targetNode.id}; |
| } else if (targetNode instanceof HTMLElement) { |
| var cvoxid = cvox.ApiUtils.nextCvoxId_; |
| targetNode.setAttribute('cvoxid', cvoxid); |
| cvox.ApiUtils.nextCvoxId_ = (cvox.ApiUtils.nextCvoxId_ + 1) % 100; |
| return {'cvoxid': cvoxid}; |
| } else if (targetNode.parentElement) { |
| var parent = targetNode.parentElement; |
| var childIndex = -1; |
| for (var i = 0; i < parent.childNodes.length; i++) { |
| if (parent.childNodes[i] == targetNode) { |
| childIndex = i; |
| break; |
| } |
| } |
| if (childIndex >= 0) { |
| var cvoxid = cvox.ApiUtils.nextCvoxId_; |
| parent.setAttribute('cvoxid', cvoxid); |
| cvox.ApiUtils.nextCvoxId_ = (cvox.ApiUtils.nextCvoxId_ + 1) % 100; |
| return {'cvoxid': cvoxid, 'childIndex': childIndex}; |
| } |
| } |
| throw 'Cannot reference node: ' + targetNode; |
| }; |
| |
| /** |
| * Retrieves a node from its serializable node reference. |
| * |
| * @param {Object} nodeRef A serializable reference to a node. |
| * @return {Node} The node on the page that this object refers to. |
| */ |
| cvox.ApiUtils.getNodeFromRef = function(nodeRef) { |
| if (nodeRef['id']) { |
| return document.getElementById(nodeRef['id']); |
| } else if (nodeRef['cvoxid']) { |
| var selector = '*[cvoxid="' + nodeRef['cvoxid'] + '"]'; |
| var element = document.querySelector(selector); |
| if (element && element.removeAttribute) { |
| element.removeAttribute('cvoxid'); |
| } |
| if (nodeRef['childIndex'] != null) { |
| return element.childNodes[nodeRef['childIndex']]; |
| } else { |
| return element; |
| } |
| } |
| throw 'Bad node reference: ' + cvox.ChromeVoxJSON.stringify(nodeRef); |
| }; |