mirror of
https://github.com/gryf/pentadactyl-pm.git
synced 2025-12-21 04:27:59 +01:00
Fix tab number updates in FF36. Closes issue 300.
This commit is contained in:
@@ -1,685 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is MozMill Test code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Henrik Skupin <hskupin@mozilla.com>
|
||||
* Adrian Kalla <akalla@aviary.pl>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// Include required modules
|
||||
var modalDialog = require("modal-dialog");
|
||||
var utils = require("utils");
|
||||
|
||||
|
||||
/**
|
||||
* Unwraps a node which is wrapped into a XPCNativeWrapper or XrayWrapper
|
||||
*
|
||||
* @param {DOMnode} Wrapped DOM node
|
||||
* @returns {DOMNode} Unwrapped DOM node
|
||||
*/
|
||||
function unwrapNode(aNode) {
|
||||
var node = aNode;
|
||||
|
||||
if (node) {
|
||||
// unwrap is not available on older branches (3.5 and 3.6) - Bug 533596
|
||||
if ("unwrap" in XPCNativeWrapper) {
|
||||
node = XPCNativeWrapper.unwrap(node);
|
||||
}
|
||||
else if ("wrappedJSObject" in node) {
|
||||
node = node.wrappedJSObject;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DOMWalker Constructor
|
||||
*
|
||||
* @param {MozMillController} controller
|
||||
* MozMill controller of the window to operate on.
|
||||
* @param {Function} callbackFilter
|
||||
* callback-method to filter nodes
|
||||
* @param {Function} callbackNodeTest
|
||||
* callback-method to test accepted nodes
|
||||
* @param {Function} callbackResults
|
||||
* callback-method to process the results
|
||||
* [optional - default: undefined]
|
||||
*/
|
||||
function DOMWalker(controller, callbackFilter, callbackNodeTest,
|
||||
callbackResults) {
|
||||
|
||||
this._controller = controller;
|
||||
this._callbackFilter = callbackFilter;
|
||||
this._callbackNodeTest = callbackNodeTest;
|
||||
this._callbackResults = callbackResults;
|
||||
}
|
||||
|
||||
DOMWalker.FILTER_ACCEPT = 1;
|
||||
DOMWalker.FILTER_REJECT = 2;
|
||||
DOMWalker.FILTER_SKIP = 3;
|
||||
|
||||
DOMWalker.GET_BY_ID = "id";
|
||||
DOMWalker.GET_BY_SELECTOR = "selector";
|
||||
|
||||
DOMWalker.WINDOW_CURRENT = 1;
|
||||
DOMWalker.WINDOW_MODAL = 2;
|
||||
DOMWalker.WINDOW_NEW = 4;
|
||||
|
||||
DOMWalker.prototype = {
|
||||
/**
|
||||
* Returns the filter-callback
|
||||
*
|
||||
* @returns Function
|
||||
*/
|
||||
get callbackFilter() {
|
||||
return this._callbackFilter;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the node-testing-callback
|
||||
*
|
||||
* @returns Function
|
||||
*/
|
||||
get callbackNodeTest() {
|
||||
return this._callbackNodeTest;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the results-callback
|
||||
*
|
||||
* @returns Function
|
||||
*/
|
||||
get callbackResults() {
|
||||
return this._callbackResults;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the MozMill controller
|
||||
*
|
||||
* @returns Mozmill controller
|
||||
* @type {MozMillController}
|
||||
*/
|
||||
get controller() {
|
||||
return this._controller;
|
||||
},
|
||||
|
||||
/**
|
||||
* The main DOMWalker function.
|
||||
*
|
||||
* It start's the _walk-method for a given window or other dialog, runs
|
||||
* a callback to process the results for that window/dialog.
|
||||
* After that switches to provided new windows/dialogs.
|
||||
*
|
||||
* @param {array of objects} ids
|
||||
* Contains informations on the elements to open while
|
||||
* Object-elements: getBy - attribute-name of the attribute
|
||||
* containing the identification
|
||||
* information for the opener-element
|
||||
* subContent - array of ids of the opener-elements
|
||||
* in the window with the value of
|
||||
* the above getBy-attribute
|
||||
* target - information, where the new
|
||||
* elements will be opened
|
||||
* [1|2|4]
|
||||
* title - title of the opened dialog/window
|
||||
* waitFunction - The function used as an argument
|
||||
* for MozmillController.waitFor to
|
||||
* wait before starting the walk.
|
||||
* [optional - default: no waiting]
|
||||
* windowHandler - Window instance
|
||||
* [only needed for some tests]
|
||||
*
|
||||
* @param {Node} root
|
||||
* Node to start testing from
|
||||
* [optional - default: this._controller.window.document.documentElement]
|
||||
* @param {Function} waitFunction
|
||||
* The function used as an argument for MozmillController.waitFor to
|
||||
* wait before starting the walk.
|
||||
* [optional - default: no waiting]
|
||||
*/
|
||||
walk : function DOMWalker_walk(ids, root, waitFunction) {
|
||||
if (typeof waitFunction == 'function')
|
||||
this._controller.waitFor(waitFunction());
|
||||
|
||||
if (!root)
|
||||
root = this._controller.window.document.documentElement;
|
||||
|
||||
var resultsArray = this._walk(root);
|
||||
|
||||
if (typeof this._callbackResults == 'function')
|
||||
this._callbackResults(this._controller, resultsArray);
|
||||
|
||||
if (ids)
|
||||
this._prepareTargetWindows(ids);
|
||||
},
|
||||
|
||||
/**
|
||||
* DOMWalker_filter filters a given node by submitting it to the
|
||||
* this._callbackFilter method to decide, if it should be submitted to
|
||||
* a provided this._callbackNodeTest method for testing (that hapens in case
|
||||
* of FILTER_ACCEPT).
|
||||
* In case of FILTER_ACCEPT and FILTER_SKIP, the children of such a node
|
||||
* will be filtered recursively.
|
||||
* Nodes with the nodeStatus "FILTER_REJECT" and their descendants will be
|
||||
* completetly ignored.
|
||||
*
|
||||
* @param {Node} node
|
||||
* Node to filter
|
||||
* @param {array of elements} collectedResults
|
||||
* An array with gathered all results from testing a given element
|
||||
* @returns An array with gathered all results from testing a given element
|
||||
* @type {array of elements}
|
||||
*/
|
||||
_filter : function DOMWalker_filter(node, collectedResults) {
|
||||
var nodeStatus = this._callbackFilter(node);
|
||||
|
||||
var nodeTestResults = [];
|
||||
|
||||
switch (nodeStatus) {
|
||||
case DOMWalker.FILTER_ACCEPT:
|
||||
nodeTestResults = this._callbackNodeTest(node);
|
||||
collectedResults = collectedResults.concat(nodeTestResults);
|
||||
// no break here as we have to perform the _walk below too
|
||||
case DOMWalker.FILTER_SKIP:
|
||||
nodeTestResults = this._walk(node);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
collectedResults = collectedResults.concat(nodeTestResults);
|
||||
|
||||
return collectedResults;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves and returns a wanted node based on the provided identification
|
||||
* set.
|
||||
*
|
||||
* @param {array of objects} idSet
|
||||
* Contains informations on the elements to open while
|
||||
* Object-elements: getBy - attribute-name of the attribute
|
||||
* containing the identification
|
||||
* information for the opener-element
|
||||
* subContent - array of ids of the opener-elements
|
||||
* in the window with the value of
|
||||
* the above getBy-attribute
|
||||
* target - information, where the new
|
||||
* elements will be opened
|
||||
* [1|2|4]
|
||||
* title - title of the opened dialog/window
|
||||
* waitFunction - The function used as an argument
|
||||
* for MozmillController.waitFor to
|
||||
* wait before starting the walk.
|
||||
* [optional - default: no waiting]
|
||||
* windowHandler - Window instance
|
||||
* [only needed for some tests]
|
||||
*
|
||||
* @returns Node
|
||||
* @type {Node}
|
||||
*/
|
||||
_getNode : function DOMWalker_getNode(idSet) {
|
||||
var doc = this._controller.window.document;
|
||||
|
||||
// QuerySelector seems to be unusuale for id's in this case:
|
||||
// https://developer.mozilla.org/En/Code_snippets/QuerySelector
|
||||
switch (idSet.getBy) {
|
||||
case DOMWalker.GET_BY_ID:
|
||||
return doc.getElementById(idSet[idSet.getBy]);
|
||||
case DOMWalker.GET_BY_SELECTOR:
|
||||
return doc.querySelector(idSet[idSet.getBy]);
|
||||
default:
|
||||
throw new Error("Not supported getBy-attribute: " + idSet.getBy);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Main entry point to open new elements like windows, tabpanels, prefpanes,
|
||||
* dialogs
|
||||
*
|
||||
* @param {array of objects} ids
|
||||
* Contains informations on the elements to open while
|
||||
* Object-elements: getBy - attribute-name of the attribute
|
||||
* containing the identification
|
||||
* information for the opener-element
|
||||
* subContent - array of ids of the opener-elements
|
||||
* in the window with the value of
|
||||
* the above getBy-attribute
|
||||
* target - information, where the new
|
||||
* elements will be opened
|
||||
* [1|2|4]
|
||||
* title - title of the opened dialog/window
|
||||
* waitFunction - The function used as an argument
|
||||
* for MozmillController.waitFor to
|
||||
* wait before starting the walk.
|
||||
* [optional - default: no waiting]
|
||||
* windowHandler - Window instance
|
||||
* [only needed for some tests]
|
||||
*/
|
||||
_prepareTargetWindows : function DOMWalker_prepareTargetWindows(ids) {
|
||||
var doc = this._controller.window.document;
|
||||
|
||||
// Go through all the provided ids
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
var node = this._getNode(ids[i]);
|
||||
|
||||
// Go further only, if the needed element exists
|
||||
if (node) {
|
||||
var idSet = ids[i];
|
||||
|
||||
// Decide if what we want to open is a new normal/modal window or if it
|
||||
// will be opened in the current window.
|
||||
switch (idSet.target) {
|
||||
case DOMWalker.WINDOW_CURRENT:
|
||||
this._processNode(node, idSet);
|
||||
break;
|
||||
case DOMWalker.WINDOW_MODAL:
|
||||
// Modal windows have to be able to access that informations
|
||||
var modalInfos = {ids : idSet.subContent,
|
||||
callbackFilter : this._callbackFilter,
|
||||
callbackNodeTest : this._callbackNodeTest,
|
||||
callbackResults : this._callbackResults,
|
||||
waitFunction : idSet.waitFunction}
|
||||
persisted.modalInfos = modalInfos;
|
||||
|
||||
var md = new modalDialog.modalDialog(this._controller.window);
|
||||
md.start(this._modalWindowHelper);
|
||||
|
||||
this._processNode(node, idSet);
|
||||
md.waitForDialog();
|
||||
break;
|
||||
case DOMWalker.WINDOW_NEW:
|
||||
this._processNode(node, idSet);
|
||||
|
||||
// Get the new non-modal window controller
|
||||
var controller = utils.handleWindow('title', idSet.title,
|
||||
undefined, false);
|
||||
|
||||
// Start a new DOMWalker instance
|
||||
let domWalker = new DOMWalker(controller, this._callbackFilter,
|
||||
this._callbackNodeTest,
|
||||
this._callbackResults);
|
||||
domWalker.walk(idSet.subContent,
|
||||
controller.window.document.documentElement,
|
||||
idSet.waitFunction);
|
||||
|
||||
// Close the window
|
||||
controller.window.close();
|
||||
break;
|
||||
default:
|
||||
throw new Error("Node does not exist: " + ids[i][ids[i].getBy]);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens new windows/dialog and starts the DOMWalker.walk() in case of dialogs
|
||||
* in existing windows.
|
||||
*
|
||||
* @param {Node} activeNode
|
||||
* Node that holds the information which way
|
||||
* to open the new window/dialog
|
||||
* @param {object} idSet
|
||||
* ID set for the element to open
|
||||
*/
|
||||
_processNode: function DOMWalker_processNode(activeNode, idSet) {
|
||||
var doc = this._controller.window.document;
|
||||
var nodeToProcess = this._getNode(idSet);
|
||||
|
||||
// Opens a new window/dialog through a menulist and runs DOMWalker.walk()
|
||||
// for it.
|
||||
// If the wanted window/dialog is already selected, just run this function
|
||||
// recursively for it's descendants.
|
||||
if (activeNode.localName == "menulist") {
|
||||
if (nodeToProcess.value != idSet.value) {
|
||||
var dropDown = new elementslib.Elem(nodeToProcess);
|
||||
this._controller.waitForElement(dropDown);
|
||||
|
||||
this._controller.select(dropDown, null, null, idSet.value);
|
||||
|
||||
this._controller.waitFor(function() {
|
||||
return nodeToProcess.value == idSet.value;
|
||||
}, "The menu item did not load in time: " + idSet.value);
|
||||
|
||||
// If the target is a new modal/non-modal window, this.walk() has to be
|
||||
// started by the method opening that window. If not, we do it here.
|
||||
if (idSet.target == DOMWalker.WINDOW_CURRENT)
|
||||
this.walk(idSet.subContent, null, idSet.waitFunction);
|
||||
} else if (nodeToProcess.selected && idSet.subContent &&
|
||||
idSet.subContent.length > 0) {
|
||||
this._prepareTargetWindows(idSet.subContent);
|
||||
}
|
||||
}
|
||||
|
||||
// Opens a new prefpane using a provided windowHandler object
|
||||
// and runs DOMWalker.walk() for it.
|
||||
// If the wanted prefpane is already selected, just run this function
|
||||
// recursively for it's descendants.
|
||||
else if (activeNode.localName == "prefpane") {
|
||||
var windowHandler = idSet.windowHandler;
|
||||
|
||||
if (windowHandler.paneId != idSet.id) {
|
||||
windowHandler.paneId = idSet.id;
|
||||
|
||||
// Wait for the pane's content to load and to be fully displayed
|
||||
this._controller.waitFor(function() {
|
||||
return (nodeToProcess.loaded &&
|
||||
(!mozmill.isMac ||
|
||||
nodeToProcess.style.opacity == 1 ||
|
||||
nodeToProcess.style.opacity == null));
|
||||
}, "The pane did not load in time: " + idSet.id);
|
||||
|
||||
// If the target is a new modal/non-modal window, this.walk() has to be
|
||||
// started by the method opening that window. If not, we do it here.
|
||||
if (idSet.target == DOMWalker.WINDOW_CURRENT)
|
||||
this.walk(idSet.subContent, null, idSet.waitFunction);
|
||||
} else if (windowHandler.paneId == idSet.id && idSet.subContent &&
|
||||
idSet.subContent.length > 0) {
|
||||
this._prepareTargetWindows(idSet.subContent);
|
||||
}
|
||||
}
|
||||
|
||||
// Switches to another tab and runs DOMWalker.walk() for it.
|
||||
// If the wanted tabpanel is already selected, just run this function
|
||||
// recursively for it's descendants.
|
||||
else if (activeNode.localName == "tab") {
|
||||
if (nodeToProcess.selected != true) {
|
||||
this._controller.click(new elementslib.Elem(nodeToProcess));
|
||||
|
||||
// If the target is a new modal/non-modal window, this.walk() has to be
|
||||
// started by the method opening that window. If not, we do it here.
|
||||
if (idSet.target == DOMWalker.WINDOW_CURRENT)
|
||||
this.walk(idSet.subContent, null, idSet.waitFunction);
|
||||
} else if (nodeToProcess.selected && idSet.subContent
|
||||
&& idSet.subContent.length > 0) {
|
||||
this._prepareTargetWindows(idSet.subContent);
|
||||
}
|
||||
}
|
||||
|
||||
// Opens a new dialog/window by clicking on an object and runs
|
||||
// DOMWalker.walk() for it.
|
||||
else {
|
||||
this._controller.click(new elementslib.Elem(nodeToProcess));
|
||||
|
||||
// If the target is a new modal/non-modal window, this.walk() has to be
|
||||
// started by the method opening that window. If not, we do it here.
|
||||
if (idSet.target == DOMWalker.WINDOW_CURRENT)
|
||||
this.walk(idSet.subContent, null, idSet.waitFunction);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* DOMWalker_walk goes recursively through the DOM, starting with a provided
|
||||
* root-node and filters the nodes using the this._filter method.
|
||||
*
|
||||
* @param {Node} root
|
||||
* Node to start testing from
|
||||
* [optional - default: this._controller.window.document.documentElement]
|
||||
* @returns An array with gathered all results from testing a given element
|
||||
* @type {array of elements}
|
||||
*/
|
||||
_walk : function DOMWalker__walk(root) {
|
||||
if (!root.childNodes)
|
||||
throw new Error("root.childNodes does not exist");
|
||||
|
||||
var collectedResults = [];
|
||||
|
||||
// There seems to be no other way to get to the nodes hidden in the
|
||||
// "_buttons" object (see Bug 614949)
|
||||
if (root._buttons) {
|
||||
for each (button in root._buttons) {
|
||||
collectedResults = this._filter(button, collectedResults);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < root.childNodes.length; i++) {
|
||||
collectedResults = this._filter(root.childNodes[i], collectedResults);
|
||||
}
|
||||
|
||||
return collectedResults;
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback function to handle new windows
|
||||
*
|
||||
* @param {MozMillController} controller
|
||||
* MozMill controller of the new window to operate on.
|
||||
*/
|
||||
_modalWindowHelper: function DOMWalker_modalWindowHelper(controller) {
|
||||
let domWalker = new DOMWalker(controller,
|
||||
persisted.modalInfos.callbackFilter,
|
||||
persisted.modalInfos.callbackNodeTest,
|
||||
persisted.modalInfos.callbackResults);
|
||||
domWalker.walk(persisted.modalInfos.ids,
|
||||
controller.window.document.documentElement,
|
||||
persisted.modalInfos.waitFunction);
|
||||
|
||||
delete persisted.modalInfos;
|
||||
|
||||
controller.window.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param {object} aRoot
|
||||
* Root node in the DOM to use as parent
|
||||
*/
|
||||
function nodeCollector(aRoot) {
|
||||
this._root = aRoot.wrappedJSObject ? aRoot.wrappedJSObject : aRoot;
|
||||
this._document = this._root.ownerDocument ? this._root.ownerDocument : this._root;
|
||||
this._nodes = [ ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Node collector class
|
||||
*/
|
||||
nodeCollector.prototype = {
|
||||
/**
|
||||
* Converts current nodes to elements
|
||||
*
|
||||
* @returns List of elements
|
||||
* @type {array of ElemBase}
|
||||
*/
|
||||
get elements() {
|
||||
var elements = [ ];
|
||||
|
||||
Array.forEach(this._nodes, function(element) {
|
||||
elements.push(new elementslib.Elem(element));
|
||||
});
|
||||
|
||||
return elements;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the current list of DOM nodes
|
||||
*
|
||||
* @returns List of nodes
|
||||
* @type {array of object}
|
||||
*/
|
||||
get nodes() {
|
||||
return this._nodes;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets current nodes to entries from the node list
|
||||
*
|
||||
* @param {array of objects} aNodeList
|
||||
* List of DOM nodes to set
|
||||
*/
|
||||
set nodes(aNodeList) {
|
||||
if (aNodeList) {
|
||||
this._nodes = [ ];
|
||||
|
||||
Array.forEach(aNodeList, function(node) {
|
||||
this._nodes.push(node);
|
||||
}, this);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the root node used as parent for a node collection
|
||||
*
|
||||
* @returns Current root node
|
||||
* @type {object}
|
||||
*/
|
||||
get root() {
|
||||
return this._root;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets root node to the specified DOM node
|
||||
*
|
||||
* @param {object} aRoot
|
||||
* DOM node to use as root for node collection
|
||||
*/
|
||||
set root(aRoot) {
|
||||
if (aRoot) {
|
||||
this._root = aRoot;
|
||||
this._nodes = [ ];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Filter nodes given by the specified callback function
|
||||
*
|
||||
* @param {function} aCallback
|
||||
* Function to test each element of the array.
|
||||
* Elements: node, index (optional) , array (optional)
|
||||
* @param {object} aThisObject
|
||||
* Object to use as 'this' when executing callback.
|
||||
* [optional - default: function scope]
|
||||
*
|
||||
* @returns The class instance
|
||||
* @type {object}
|
||||
*/
|
||||
filter : function nodeCollector_filter(aCallback, aThisObject) {
|
||||
if (!aCallback)
|
||||
throw new Error(arguments.callee.name + ": No callback specified");
|
||||
|
||||
this.nodes = Array.filter(this.nodes, aCallback, aThisObject);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Filter nodes by DOM property and its value
|
||||
*
|
||||
* @param {string} aProperty
|
||||
* Property to filter for
|
||||
* @param {string} aValue
|
||||
* Expected value of the DOM property
|
||||
* [optional - default: n/a]
|
||||
*
|
||||
* @returns The class instance
|
||||
* @type {object}
|
||||
*/
|
||||
filterByDOMProperty : function nodeCollector_filterByDOMProperty(aProperty, aValue) {
|
||||
return this.filter(function(node) {
|
||||
if (aProperty && aValue)
|
||||
return node.getAttribute(aProperty) == aValue;
|
||||
else if (aProperty)
|
||||
return node.hasAttribute(aProperty);
|
||||
else
|
||||
return true;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Filter nodes by JS property and its value
|
||||
*
|
||||
* @param {string} aProperty
|
||||
* Property to filter for
|
||||
* @param {string} aValue
|
||||
* Expected value of the JS property
|
||||
* [optional - default: n/a]
|
||||
*
|
||||
* @returns The class instance
|
||||
* @type {object}
|
||||
*/
|
||||
filterByJSProperty : function nodeCollector_filterByJSProperty(aProperty, aValue) {
|
||||
return this.filter(function(node) {
|
||||
if (aProperty && aValue)
|
||||
return node.aProperty == aValue;
|
||||
else if (aProperty)
|
||||
return node.aProperty !== undefined;
|
||||
else
|
||||
return true;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Find anonymouse nodes with the specified attribute and value
|
||||
*
|
||||
* @param {string} aAttribute
|
||||
* DOM attribute of the wanted node
|
||||
* @param {string} aValue
|
||||
* Value of the DOM attribute
|
||||
*
|
||||
* @returns The class instance
|
||||
* @type {object}
|
||||
*/
|
||||
queryAnonymousNodes : function nodeCollector_queryAnonymousNodes(aAttribute, aValue) {
|
||||
var node = this._document.getAnonymousElementByAttribute(this._root,
|
||||
aAttribute,
|
||||
aValue);
|
||||
this.nodes = node ? [node] : [ ];
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Find nodes with the specified selector
|
||||
*
|
||||
* @param {string} aSelector
|
||||
* jQuery like element selector string
|
||||
*
|
||||
* @returns The class instance
|
||||
* @type {object}
|
||||
*/
|
||||
queryNodes : function nodeCollector_queryNodes(aSelector) {
|
||||
this.nodes = this._root.querySelectorAll(aSelector);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
// Exports of functions
|
||||
exports.unwrapNode = unwrapNode;
|
||||
|
||||
// Exports of classes
|
||||
exports.DOMWalker = DOMWalker;
|
||||
exports.nodeCollector = nodeCollector;
|
||||
Reference in New Issue
Block a user