зеркало из https://github.com/mozilla/pjs.git
Bug 753099 Update peptest to work with global compartments change r=ctalbert
This commit is contained in:
Родитель
676d0559b4
Коммит
6a076cbab9
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,57 +1,28 @@
|
|||
// ***** BEGIN LICENSE BLOCK *****// ***** 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 Mozilla Corporation Code.
|
||||
//
|
||||
// The Initial Developer of the Original Code is
|
||||
// Adam Christian.
|
||||
// Portions created by the Initial Developer are Copyright (C) 2008
|
||||
// the Initial Developer. All Rights Reserved.
|
||||
//
|
||||
// Contributor(s):
|
||||
// Adam Christian <adam.christian@gmail.com>
|
||||
// Mikeal Rogers <mikeal.rogers@gmail.com>
|
||||
//
|
||||
// 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 *****
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var EXPORTED_SYMBOLS = ["Elem", "ID", "Link", "XPath", "Selector", "Name", "Anon", "AnonXPath",
|
||||
"Lookup", "_byID", "_byName", "_byAttrib", "_byAnonAttrib",
|
||||
];
|
||||
|
||||
var utils = {}; Components.utils.import('resource://mozmill/stdlib/utils.js', utils);
|
||||
var strings = {}; Components.utils.import('resource://mozmill/stdlib/strings.js', strings);
|
||||
var arrays = {}; Components.utils.import('resource://mozmill/stdlib/arrays.js', arrays);
|
||||
var json2 = {}; Components.utils.import('resource://mozmill/stdlib/json2.js', json2);
|
||||
var withs = {}; Components.utils.import('resource://mozmill/stdlib/withs.js', withs);
|
||||
var dom = {}; Components.utils.import('resource://mozmill/stdlib/dom.js', dom);
|
||||
var objects = {}; Components.utils.import('resource://mozmill/stdlib/objects.js', objects);
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
var countQuotes = function(str){
|
||||
var utils = {}; Cu.import('resource://mozmill/stdlib/utils.js', utils);
|
||||
var strings = {}; Cu.import('resource://mozmill/stdlib/strings.js', strings);
|
||||
var arrays = {}; Cu.import('resource://mozmill/stdlib/arrays.js', arrays);
|
||||
var json2 = {}; Cu.import('resource://mozmill/stdlib/json2.js', json2);
|
||||
var withs = {}; Cu.import('resource://mozmill/stdlib/withs.js', withs);
|
||||
var dom = {}; Cu.import('resource://mozmill/stdlib/dom.js', dom);
|
||||
var objects = {}; Cu.import('resource://mozmill/stdlib/objects.js', objects);
|
||||
|
||||
var countQuotes = function (str) {
|
||||
var count = 0;
|
||||
var i = 0;
|
||||
while(i < str.length) {
|
||||
|
||||
while (i < str.length) {
|
||||
i = str.indexOf('"', i);
|
||||
if (i != -1) {
|
||||
count++;
|
||||
|
@ -60,6 +31,7 @@ var countQuotes = function(str){
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
};
|
||||
|
||||
|
@ -74,7 +46,7 @@ var smartSplit = function (str) {
|
|||
if (countQuotes(str) % 2 != 0) {
|
||||
throw new Error ("Invalid Lookup Expression");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This regex matches a single "node" in a lookup string.
|
||||
* In otherwords, it matches the part between the two '/'s
|
||||
|
@ -87,10 +59,12 @@ var smartSplit = function (str) {
|
|||
var re = /\/([^\/"]*"[^"]*")*[^\/]*/g
|
||||
var ret = []
|
||||
var match = re.exec(str);
|
||||
|
||||
while (match != null) {
|
||||
ret.push(match[0].replace(/^\//, ""));
|
||||
match = re.exec(str);
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
@ -101,9 +75,11 @@ var smartSplit = function (str) {
|
|||
* if no document is provided
|
||||
*/
|
||||
function defaultDocuments() {
|
||||
var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator);
|
||||
win = windowManager.getMostRecentWindow("navigator:browser");
|
||||
return [win.gBrowser.selectedBrowser.contentDocument, win.document];
|
||||
var win = Cc['@mozilla.org/appshell/window-mediator;1']
|
||||
.getService(Ci.nsIWindowMediator)
|
||||
.getMostRecentWindow("navigator:browser");
|
||||
|
||||
return [win.getBrowser().contentDocument, win.document];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -118,30 +94,37 @@ function nodeSearch(doc, func, string) {
|
|||
} else {
|
||||
var documents = defaultDocuments();
|
||||
}
|
||||
|
||||
var e = null;
|
||||
var element = null;
|
||||
|
||||
//inline function to recursively find the element in the DOM, cross frame.
|
||||
var search = function(win, func, string) {
|
||||
if (win == null)
|
||||
var search = function (win, func, string) {
|
||||
if (win == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
//do the lookup in the current window
|
||||
element = func.call(win, string);
|
||||
|
||||
|
||||
if (!element || (element.length == 0)) {
|
||||
var frames = win.frames;
|
||||
for (var i=0; i < frames.length; i++) {
|
||||
for (var i = 0; i < frames.length; i++) {
|
||||
search(frames[i], func, string);
|
||||
}
|
||||
} else {
|
||||
e = element;
|
||||
}
|
||||
else { e = element; }
|
||||
};
|
||||
|
||||
|
||||
for (var i = 0; i < documents.length; ++i) {
|
||||
var win = documents[i].defaultView;
|
||||
search(win, func, string);
|
||||
if (e) break;
|
||||
if (e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return e;
|
||||
};
|
||||
|
||||
|
@ -154,11 +137,15 @@ function Selector(_document, selector, index) {
|
|||
if (selector == undefined) {
|
||||
throw new Error('Selector constructor did not recieve enough arguments.');
|
||||
}
|
||||
|
||||
this.selector = selector;
|
||||
|
||||
this.getNodeForDocument = function (s) {
|
||||
return this.document.querySelectorAll(s);
|
||||
};
|
||||
|
||||
var nodes = nodeSearch(_document, this.getNodeForDocument, this.selector);
|
||||
|
||||
return nodes ? nodes[index || 0] : null;
|
||||
};
|
||||
|
||||
|
@ -171,9 +158,11 @@ function ID(_document, nodeID) {
|
|||
if (nodeID == undefined) {
|
||||
throw new Error('ID constructor did not recieve enough arguments.');
|
||||
}
|
||||
|
||||
this.getNodeForDocument = function (nodeID) {
|
||||
return this.document.getElementById(nodeID);
|
||||
};
|
||||
|
||||
return nodeSearch(_document, this.getNodeForDocument, nodeID);
|
||||
};
|
||||
|
||||
|
@ -186,45 +175,53 @@ function Link(_document, linkName) {
|
|||
if (linkName == undefined) {
|
||||
throw new Error('Link constructor did not recieve enough arguments.');
|
||||
}
|
||||
|
||||
|
||||
this.getNodeForDocument = function (linkName) {
|
||||
var getText = function(el){
|
||||
var getText = function (el) {
|
||||
var text = "";
|
||||
if (el.nodeType == 3){ //textNode
|
||||
if (el.data != undefined){
|
||||
|
||||
if (el.nodeType == 3) { //textNode
|
||||
if (el.data != undefined) {
|
||||
text = el.data;
|
||||
} else {
|
||||
text = el.innerHTML;
|
||||
}
|
||||
text = text.replace(/n|r|t/g, " ");
|
||||
|
||||
text = text.replace(/n|r|t/g, " ");
|
||||
}
|
||||
if (el.nodeType == 1){ //elementNode
|
||||
else if (el.nodeType == 1) { //elementNode
|
||||
for (var i = 0; i < el.childNodes.length; i++) {
|
||||
var child = el.childNodes.item(i);
|
||||
text += getText(child);
|
||||
}
|
||||
if (el.tagName == "P" || el.tagName == "BR" || el.tagName == "HR" || el.tagName == "DIV") {
|
||||
text += "n";
|
||||
|
||||
if (el.tagName == "P" || el.tagName == "BR" ||
|
||||
el.tagName == "HR" || el.tagName == "DIV") {
|
||||
text += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
};
|
||||
|
||||
|
||||
//sometimes the windows won't have this function
|
||||
try {
|
||||
var links = this.document.getElementsByTagName('a'); }
|
||||
catch(err){ // ADD LOG LINE mresults.write('Error: '+ err, 'lightred');
|
||||
try {
|
||||
var links = this.document.getElementsByTagName('a');
|
||||
} catch (e) {
|
||||
// ADD LOG LINE mresults.write('Error: '+ e, 'lightred');
|
||||
}
|
||||
|
||||
for (var i = 0; i < links.length; i++) {
|
||||
var el = links[i];
|
||||
//if (getText(el).indexOf(this.linkName) != -1) {
|
||||
if (el.innerHTML.indexOf(linkName) != -1){
|
||||
if (el.innerHTML.indexOf(linkName) != -1) {
|
||||
return el;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
return nodeSearch(_document, this.getNodeForDocument, linkName);
|
||||
};
|
||||
|
||||
|
@ -237,7 +234,7 @@ function XPath(_document, expr) {
|
|||
if (expr == undefined) {
|
||||
throw new Error('XPath constructor did not recieve enough arguments.');
|
||||
}
|
||||
|
||||
|
||||
this.getNodeForDocument = function (s) {
|
||||
var aNode = this.document;
|
||||
var aExpr = s;
|
||||
|
@ -248,14 +245,20 @@ function XPath(_document, expr) {
|
|||
} else {
|
||||
xpe = new this.document.defaultView.XPathEvaluator();
|
||||
}
|
||||
var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ? aNode.documentElement : aNode.ownerDocument.documentElement);
|
||||
|
||||
var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ? aNode.documentElement
|
||||
: aNode.ownerDocument.documentElement);
|
||||
var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
|
||||
var found = [];
|
||||
var res;
|
||||
while (res = result.iterateNext())
|
||||
|
||||
while (res = result.iterateNext()) {
|
||||
found.push(res);
|
||||
}
|
||||
|
||||
return found[0];
|
||||
};
|
||||
|
||||
return nodeSearch(_document, this.getNodeForDocument, expr);
|
||||
};
|
||||
|
||||
|
@ -268,14 +271,19 @@ function Name(_document, nName) {
|
|||
if (nName == undefined) {
|
||||
throw new Error('Name constructor did not recieve enough arguments.');
|
||||
}
|
||||
|
||||
this.getNodeForDocument = function (s) {
|
||||
try{
|
||||
var els = this.document.getElementsByName(s);
|
||||
if (els.length > 0) { return els[0]; }
|
||||
if (els.length > 0) {
|
||||
return els[0];
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
catch(err){};
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
return nodeSearch(_document, this.getNodeForDocument, nName);
|
||||
};
|
||||
|
||||
|
@ -283,110 +291,138 @@ function Name(_document, nName) {
|
|||
var _returnResult = function (results) {
|
||||
if (results.length == 0) {
|
||||
return null
|
||||
} else if (results.length == 1) {
|
||||
}
|
||||
else if (results.length == 1) {
|
||||
return results[0];
|
||||
} else {
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
var _forChildren = function (element, name, value) {
|
||||
var results = [];
|
||||
var nodes = [e for each (e in element.childNodes) if (e)]
|
||||
|
||||
for (var i in nodes) {
|
||||
var n = nodes[i];
|
||||
if (n[name] == value) {
|
||||
results.push(n);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
var _forAnonChildren = function (_document, element, name, value) {
|
||||
var results = [];
|
||||
var nodes = [e for each (e in _document.getAnoymousNodes(element)) if (e)];
|
||||
|
||||
for (var i in nodes ) {
|
||||
var n = nodes[i];
|
||||
if (n[name] == value) {
|
||||
results.push(n);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
var _byID = function (_document, parent, value) {
|
||||
return _returnResult(_forChildren(parent, 'id', value));
|
||||
}
|
||||
|
||||
var _byName = function (_document, parent, value) {
|
||||
return _returnResult(_forChildren(parent, 'tagName', value));
|
||||
}
|
||||
|
||||
var _byAttrib = function (parent, attributes) {
|
||||
var results = [];
|
||||
|
||||
var nodes = parent.childNodes;
|
||||
|
||||
for (var i in nodes) {
|
||||
var n = nodes[i];
|
||||
requirementPass = 0;
|
||||
requirementLength = 0;
|
||||
|
||||
for (var a in attributes) {
|
||||
requirementLength++;
|
||||
try {
|
||||
if (n.getAttribute(a) == attributes[a]) {
|
||||
requirementPass++;
|
||||
}
|
||||
} catch (err) {
|
||||
} catch (e) {
|
||||
// Workaround any bugs in custom attribute crap in XUL elements
|
||||
}
|
||||
}
|
||||
|
||||
if (requirementPass == requirementLength) {
|
||||
results.push(n);
|
||||
}
|
||||
}
|
||||
|
||||
return _returnResult(results)
|
||||
}
|
||||
|
||||
var _byAnonAttrib = function (_document, parent, attributes) {
|
||||
var results = [];
|
||||
|
||||
|
||||
if (objects.getLength(attributes) == 1) {
|
||||
for (var i in attributes) {var k = i; var v = attributes[i]; }
|
||||
var result = _document.getAnonymousElementByAttribute(parent, k, v)
|
||||
for (var i in attributes) {
|
||||
var k = i;
|
||||
var v = attributes[i];
|
||||
}
|
||||
|
||||
var result = _document.getAnonymousElementByAttribute(parent, k, v);
|
||||
if (result) {
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var nodes = [n for each (n in _document.getAnonymousNodes(parent)) if (n.getAttribute)];
|
||||
|
||||
function resultsForNodes (nodes) {
|
||||
for (var i in nodes) {
|
||||
var n = nodes[i];
|
||||
requirementPass = 0;
|
||||
requirementLength = 0;
|
||||
|
||||
for (var a in attributes) {
|
||||
requirementLength++;
|
||||
if (n.getAttribute(a) == attributes[a]) {
|
||||
requirementPass++;
|
||||
}
|
||||
}
|
||||
|
||||
if (requirementPass == requirementLength) {
|
||||
results.push(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
resultsForNodes(nodes)
|
||||
}
|
||||
|
||||
resultsForNodes(nodes);
|
||||
if (results.length == 0) {
|
||||
resultsForNodes([n for each (n in parent.childNodes) if (n != undefined && n.getAttribute)])
|
||||
}
|
||||
|
||||
return _returnResult(results)
|
||||
}
|
||||
|
||||
var _byIndex = function (_document, parent, i) {
|
||||
if (parent instanceof Array) {
|
||||
return parent[i];
|
||||
}
|
||||
|
||||
return parent.childNodes[i];
|
||||
}
|
||||
|
||||
var _anonByName = function (_document, parent, value) {
|
||||
return _returnResult(_forAnonChildren(_document, parent, 'tagName', value));
|
||||
}
|
||||
|
||||
var _anonByAttrib = function (_document, parent, value) {
|
||||
return _byAnonAttrib(_document, parent, value);
|
||||
}
|
||||
|
||||
var _anonByIndex = function (_document, parent, i) {
|
||||
return _document.getAnonymousNodes(parent)[i];
|
||||
}
|
||||
|
@ -396,73 +432,82 @@ var _anonByIndex = function (_document, parent, i) {
|
|||
*
|
||||
* Finds an element by Lookup expression
|
||||
*/
|
||||
function Lookup (_document, expression) {
|
||||
function Lookup(_document, expression) {
|
||||
if (expression == undefined) {
|
||||
throw new Error('Lookup constructor did not recieve enough arguments.');
|
||||
}
|
||||
|
||||
var expSplit = [e for each (e in smartSplit(expression) ) if (e != '')];
|
||||
expSplit.unshift(_document)
|
||||
expSplit.unshift(_document);
|
||||
|
||||
var nCases = {'id':_byID, 'name':_byName, 'attrib':_byAttrib, 'index':_byIndex};
|
||||
var aCases = {'name':_anonByName, 'attrib':_anonByAttrib, 'index':_anonByIndex};
|
||||
|
||||
|
||||
|
||||
var reduceLookup = function (parent, exp) {
|
||||
// Handle case where only index is provided
|
||||
var cases = nCases;
|
||||
|
||||
|
||||
// Handle ending index before any of the expression gets mangled
|
||||
if (withs.endsWith(exp, ']')) {
|
||||
var expIndex = json2.JSON.parse(strings.vslice(exp, '[', ']'));
|
||||
}
|
||||
|
||||
// Handle anon
|
||||
if (withs.startsWith(exp, 'anon')) {
|
||||
var exp = strings.vslice(exp, '(', ')');
|
||||
var cases = aCases;
|
||||
exp = strings.vslice(exp, '(', ')');
|
||||
cases = aCases;
|
||||
}
|
||||
|
||||
if (withs.startsWith(exp, '[')) {
|
||||
try {
|
||||
var obj = json2.JSON.parse(strings.vslice(exp, '[', ']'));
|
||||
} catch (err) {
|
||||
throw new Error(err+'. String to be parsed was || '+strings.vslice(exp, '[', ']')+' ||');
|
||||
} catch (e) {
|
||||
throw new Error(e + '. String to be parsed was || ' +
|
||||
strings.vslice(exp, '[', ']') + ' ||');
|
||||
}
|
||||
|
||||
var r = cases['index'](_document, parent, obj);
|
||||
if (r == null) {
|
||||
throw new Error('Expression "'+exp+'" returned null. Anonymous == '+(cases == aCases));
|
||||
throw new Error('Expression "' + exp +
|
||||
'" returned null. Anonymous == ' + (cases == aCases));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
for (var c in cases) {
|
||||
if (withs.startsWith(exp, c)) {
|
||||
try {
|
||||
var obj = json2.JSON.parse(strings.vslice(exp, '(', ')'))
|
||||
} catch(err) {
|
||||
throw new Error(err+'. String to be parsed was || '+strings.vslice(exp, '(', ')')+' ||');
|
||||
} catch (e) {
|
||||
throw new Error(e + '. String to be parsed was || ' +
|
||||
strings.vslice(exp, '(', ')') + ' ||');
|
||||
}
|
||||
var result = cases[c](_document, parent, obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!result) {
|
||||
if ( withs.startsWith(exp, '{') ) {
|
||||
try {
|
||||
var obj = json2.JSON.parse(exp)
|
||||
} catch(err) {
|
||||
throw new Error(err+'. String to be parsed was || '+exp+' ||');
|
||||
var obj = json2.JSON.parse(exp);
|
||||
} catch (e) {
|
||||
throw new Error(e + '. String to be parsed was || ' + exp + ' ||');
|
||||
}
|
||||
|
||||
|
||||
if (cases == aCases) {
|
||||
var result = _anonByAttrib(_document, parent, obj)
|
||||
var result = _anonByAttrib(_document, parent, obj);
|
||||
} else {
|
||||
var result = _byAttrib(parent, obj)
|
||||
var result = _byAttrib(parent, obj);
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
throw new Error('Expression "'+exp+'" returned null. Anonymous == '+(cases == aCases));
|
||||
throw new Error('Expression "' + exp +
|
||||
'" returned null. Anonymous == ' + (cases == aCases));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Final return
|
||||
if (expIndex) {
|
||||
// TODO: Check length and raise error
|
||||
|
@ -471,8 +516,10 @@ function Lookup (_document, expression) {
|
|||
// TODO: Check length and raise error
|
||||
return result;
|
||||
}
|
||||
|
||||
// Maybe we should cause an exception here
|
||||
return false;
|
||||
};
|
||||
|
||||
return expSplit.reduce(reduceLookup);
|
||||
};
|
||||
|
|
|
@ -1,50 +1,22 @@
|
|||
/* ***** 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 Elements.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Andrew Halberstadt <halbersa@gmail.com>
|
||||
*
|
||||
* 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 ***** */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var EXPORTED_SYMBOLS = ["Elem", "Selector", "ID", "Link", "XPath", "Name", "Lookup",
|
||||
"MozMillElement", "MozMillCheckBox", "MozMillRadio", "MozMillDropList",
|
||||
"MozMillTextBox", "subclasses",
|
||||
];
|
||||
|
||||
var EventUtils = {}; Components.utils.import('resource://mozmill/stdlib/EventUtils.js', EventUtils);
|
||||
var utils = {}; Components.utils.import('resource://mozmill/stdlib/utils.js', utils);
|
||||
var elementslib = {}; Components.utils.import('resource://mozmill/driver/elementslib.js', elementslib);
|
||||
var broker = {}; Components.utils.import('resource://mozmill/driver/msgbroker.js', broker);
|
||||
const NAMESPACE_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
var EventUtils = {}; Cu.import('resource://mozmill/stdlib/EventUtils.js', EventUtils);
|
||||
|
||||
var broker = {}; Cu.import('resource://mozmill/driver/msgbroker.js', broker);
|
||||
var elementslib = {}; Cu.import('resource://mozmill/driver/elementslib.js', elementslib);
|
||||
var utils = {}; Cu.import('resource://mozmill/stdlib/utils.js', utils);
|
||||
|
||||
// A list of all the subclasses available. Shared modules can push their own subclasses onto this list
|
||||
var subclasses = [MozMillCheckBox, MozMillRadio, MozMillDropList, MozMillTextBox];
|
||||
|
@ -64,40 +36,43 @@ function createInstance(locatorType, locator, elem, document) {
|
|||
return new subclasses[i](locatorType, locator, args);
|
||||
}
|
||||
}
|
||||
if (MozMillElement.isType(elem)) return new MozMillElement(locatorType, locator, args);
|
||||
|
||||
if (MozMillElement.isType(elem)) {
|
||||
return new MozMillElement(locatorType, locator, args);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error("could not find element " + locatorType + ": " + locator);
|
||||
};
|
||||
|
||||
var Elem = function(node) {
|
||||
var Elem = function (node) {
|
||||
return createInstance("Elem", node, node);
|
||||
};
|
||||
|
||||
var Selector = function(document, selector, index) {
|
||||
var Selector = function (document, selector, index) {
|
||||
return createInstance("Selector", selector, elementslib.Selector(document, selector, index), document);
|
||||
};
|
||||
|
||||
var ID = function(document, nodeID) {
|
||||
var ID = function (document, nodeID) {
|
||||
return createInstance("ID", nodeID, elementslib.ID(document, nodeID), document);
|
||||
};
|
||||
|
||||
var Link = function(document, linkName) {
|
||||
var Link = function (document, linkName) {
|
||||
return createInstance("Link", linkName, elementslib.Link(document, linkName), document);
|
||||
};
|
||||
|
||||
var XPath = function(document, expr) {
|
||||
var XPath = function (document, expr) {
|
||||
return createInstance("XPath", expr, elementslib.XPath(document, expr), document);
|
||||
};
|
||||
|
||||
var Name = function(document, nName) {
|
||||
var Name = function (document, nName) {
|
||||
return createInstance("Name", nName, elementslib.Name(document, nName), document);
|
||||
};
|
||||
|
||||
var Lookup = function(document, expression) {
|
||||
var Lookup = function (document, expression) {
|
||||
return createInstance("Lookup", expression, elementslib.Lookup(document, expression), document);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* MozMillElement
|
||||
* The base class for all mozmill elements
|
||||
|
@ -114,30 +89,32 @@ function MozMillElement(locatorType, locator, args) {
|
|||
}
|
||||
|
||||
// Static method that returns true if node is of this element type
|
||||
MozMillElement.isType = function(node) {
|
||||
MozMillElement.isType = function (node) {
|
||||
return true;
|
||||
};
|
||||
|
||||
// This getter is the magic behind lazy loading (note distinction between _element and element)
|
||||
MozMillElement.prototype.__defineGetter__("element", function() {
|
||||
MozMillElement.prototype.__defineGetter__("element", function () {
|
||||
if (this._element == undefined) {
|
||||
if (elementslib[this._locatorType]) {
|
||||
this._element = elementslib[this._locatorType](this._document, this._locator);
|
||||
} else if (this._locatorType == "Elem") {
|
||||
}
|
||||
else if (this._locatorType == "Elem") {
|
||||
this._element = this._locator;
|
||||
} else {
|
||||
throw new Error("Unknown locator type: " + this._locatorType);
|
||||
}
|
||||
}
|
||||
|
||||
return this._element;
|
||||
});
|
||||
|
||||
// Returns the actual wrapped DOM node
|
||||
MozMillElement.prototype.getNode = function() {
|
||||
MozMillElement.prototype.getNode = function () {
|
||||
return this.element;
|
||||
};
|
||||
|
||||
MozMillElement.prototype.getInfo = function() {
|
||||
MozMillElement.prototype.getInfo = function () {
|
||||
return this._locatorType + ": " + this._locator;
|
||||
};
|
||||
|
||||
|
@ -145,9 +122,12 @@ MozMillElement.prototype.getInfo = function() {
|
|||
* Sometimes an element which once existed will no longer exist in the DOM
|
||||
* This function re-searches for the element
|
||||
*/
|
||||
MozMillElement.prototype.exists = function() {
|
||||
MozMillElement.prototype.exists = function () {
|
||||
this._element = undefined;
|
||||
if (this.element) return true;
|
||||
if (this.element) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -175,23 +155,26 @@ MozMillElement.prototype.exists = function() {
|
|||
* [optional - default: current element]
|
||||
* type - Type of the expected key event
|
||||
*/
|
||||
MozMillElement.prototype.keypress = function(aKey, aModifiers, aExpectedEvent) {
|
||||
MozMillElement.prototype.keypress = function (aKey, aModifiers, aExpectedEvent) {
|
||||
if (!this.element) {
|
||||
throw new Error("Could not find element " + this.getInfo());
|
||||
}
|
||||
|
||||
var win = this.element.ownerDocument? this.element.ownerDocument.defaultView : this.element;
|
||||
var win = this.element.ownerDocument ? this.element.ownerDocument.defaultView
|
||||
: this.element;
|
||||
this.element.focus();
|
||||
|
||||
if (aExpectedEvent) {
|
||||
var target = aExpectedEvent.target? aExpectedEvent.target.getNode() : this.element;
|
||||
var target = aExpectedEvent.target ? aExpectedEvent.target.getNode()
|
||||
: this.element;
|
||||
EventUtils.synthesizeKeyExpectEvent(aKey, aModifiers || {}, target, aExpectedEvent.type,
|
||||
"MozMillElement.keypress()", win);
|
||||
"MozMillElement.keypress()", win);
|
||||
} else {
|
||||
EventUtils.synthesizeKey(aKey, aModifiers || {}, win);
|
||||
}
|
||||
|
||||
broker.pass({'function':'MozMillElement.keypress()'});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -230,7 +213,7 @@ MozMillElement.prototype.keypress = function(aKey, aModifiers, aExpectedEvent) {
|
|||
* [optional - default: current element]
|
||||
* type - Type of the expected mouse event
|
||||
*/
|
||||
MozMillElement.prototype.mouseEvent = function(aOffsetX, aOffsetY, aEvent, aExpectedEvent) {
|
||||
MozMillElement.prototype.mouseEvent = function (aOffsetX, aOffsetY, aEvent, aExpectedEvent) {
|
||||
if (!this.element) {
|
||||
throw new Error(arguments.callee.name + ": could not find element " + this.getInfo());
|
||||
}
|
||||
|
@ -240,6 +223,7 @@ MozMillElement.prototype.mouseEvent = function(aOffsetX, aOffsetY, aEvent, aExpe
|
|||
if (isNaN(aOffsetX)) {
|
||||
aOffsetX = rect.width / 2;
|
||||
}
|
||||
|
||||
if (isNaN(aOffsetY)) {
|
||||
aOffsetY = rect.height / 2;
|
||||
}
|
||||
|
@ -251,13 +235,16 @@ MozMillElement.prototype.mouseEvent = function(aOffsetX, aOffsetY, aEvent, aExpe
|
|||
|
||||
if (aExpectedEvent) {
|
||||
// The expected event type has to be set
|
||||
if (!aExpectedEvent.type)
|
||||
if (!aExpectedEvent.type) {
|
||||
throw new Error(arguments.callee.name + ": Expected event type not specified");
|
||||
}
|
||||
|
||||
// If no target has been specified use the specified element
|
||||
var target = aExpectedEvent.target ? aExpectedEvent.target.getNode() : this.element;
|
||||
var target = aExpectedEvent.target ? aExpectedEvent.target.getNode()
|
||||
: this.element;
|
||||
if (!target) {
|
||||
throw new Error(arguments.callee.name + ": could not find element " + aExpectedEvent.target.getInfo());
|
||||
throw new Error(arguments.callee.name + ": could not find element " +
|
||||
aExpectedEvent.target.getInfo());
|
||||
}
|
||||
|
||||
EventUtils.synthesizeMouseExpectEvent(this.element, aOffsetX, aOffsetY, aEvent,
|
||||
|
@ -268,12 +255,14 @@ MozMillElement.prototype.mouseEvent = function(aOffsetX, aOffsetY, aEvent, aExpe
|
|||
EventUtils.synthesizeMouse(this.element, aOffsetX, aOffsetY, aEvent,
|
||||
this.element.ownerDocument.defaultView);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Synthesize a mouse click event on the given element
|
||||
*/
|
||||
MozMillElement.prototype.click = function(left, top, expectedEvent) {
|
||||
MozMillElement.prototype.click = function (left, top, expectedEvent) {
|
||||
// Handle menu items differently
|
||||
if (this.element && this.element.tagName == "menuitem") {
|
||||
this.element.click();
|
||||
|
@ -282,15 +271,18 @@ MozMillElement.prototype.click = function(left, top, expectedEvent) {
|
|||
}
|
||||
|
||||
broker.pass({'function':'MozMillElement.click()'});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Synthesize a double click on the given element
|
||||
*/
|
||||
MozMillElement.prototype.doubleClick = function(left, top, expectedEvent) {
|
||||
MozMillElement.prototype.doubleClick = function (left, top, expectedEvent) {
|
||||
this.mouseEvent(left, top, {clickCount: 2}, expectedEvent);
|
||||
|
||||
broker.pass({'function':'MozMillElement.doubleClick()'});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -301,6 +293,7 @@ MozMillElement.prototype.mouseDown = function (button, left, top, expectedEvent)
|
|||
this.mouseEvent(left, top, {button: button, type: "mousedown"}, expectedEvent);
|
||||
|
||||
broker.pass({'function':'MozMillElement.mouseDown()'});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -311,6 +304,7 @@ MozMillElement.prototype.mouseOut = function (button, left, top, expectedEvent)
|
|||
this.mouseEvent(left, top, {button: button, type: "mouseout"}, expectedEvent);
|
||||
|
||||
broker.pass({'function':'MozMillElement.mouseOut()'});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -321,6 +315,7 @@ MozMillElement.prototype.mouseOver = function (button, left, top, expectedEvent)
|
|||
this.mouseEvent(left, top, {button: button, type: "mouseover"}, expectedEvent);
|
||||
|
||||
broker.pass({'function':'MozMillElement.mouseOver()'});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -331,48 +326,54 @@ MozMillElement.prototype.mouseUp = function (button, left, top, expectedEvent) {
|
|||
this.mouseEvent(left, top, {button: button, type: "mouseup"}, expectedEvent);
|
||||
|
||||
broker.pass({'function':'MozMillElement.mouseUp()'});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Synthesize a mouse middle click event on the given element
|
||||
*/
|
||||
MozMillElement.prototype.middleClick = function(left, top, expectedEvent) {
|
||||
MozMillElement.prototype.middleClick = function (left, top, expectedEvent) {
|
||||
this.mouseEvent(left, top, {button: 1}, expectedEvent);
|
||||
|
||||
broker.pass({'function':'MozMillElement.middleClick()'});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Synthesize a mouse right click event on the given element
|
||||
*/
|
||||
MozMillElement.prototype.rightClick = function(left, top, expectedEvent) {
|
||||
MozMillElement.prototype.rightClick = function (left, top, expectedEvent) {
|
||||
this.mouseEvent(left, top, {type : "contextmenu", button: 2 }, expectedEvent);
|
||||
|
||||
broker.pass({'function':'MozMillElement.rightClick()'});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
MozMillElement.prototype.waitForElement = function(timeout, interval) {
|
||||
MozMillElement.prototype.waitForElement = function (timeout, interval) {
|
||||
var elem = this;
|
||||
utils.waitFor(function() {
|
||||
|
||||
utils.waitFor(function () {
|
||||
return elem.exists();
|
||||
}, "Timeout exceeded for waitForElement " + this.getInfo(), timeout, interval);
|
||||
|
||||
broker.pass({'function':'MozMillElement.waitForElement()'});
|
||||
};
|
||||
|
||||
MozMillElement.prototype.waitForElementNotPresent = function(timeout, interval) {
|
||||
MozMillElement.prototype.waitForElementNotPresent = function (timeout, interval) {
|
||||
var elem = this;
|
||||
utils.waitFor(function() {
|
||||
|
||||
utils.waitFor(function () {
|
||||
return !elem.exists();
|
||||
}, "Timeout exceeded for waitForElementNotPresent " + this.getInfo(), timeout, interval);
|
||||
|
||||
broker.pass({'function':'MozMillElement.waitForElementNotPresent()'});
|
||||
};
|
||||
|
||||
MozMillElement.prototype.waitThenClick = function (timeout, interval, left, top, expectedEvent) {
|
||||
MozMillElement.prototype.waitThenClick = function (timeout, interval,
|
||||
left, top, expectedEvent) {
|
||||
this.waitForElement(timeout, interval);
|
||||
this.click(left, top, expectedEvent);
|
||||
};
|
||||
|
@ -386,6 +387,7 @@ MozMillElement.prototype.dispatchEvent = function (eventType, canBubble, modifie
|
|||
evt.altKey = modifiers["alt"];
|
||||
evt.ctrlKey = modifiers["ctrl"];
|
||||
evt.initEvent(eventType, canBubble, true);
|
||||
|
||||
this.element.dispatchEvent(evt);
|
||||
};
|
||||
|
||||
|
@ -405,28 +407,28 @@ function MozMillCheckBox(locatorType, locator, args) {
|
|||
}
|
||||
|
||||
// Static method returns true if node is this type of element
|
||||
MozMillCheckBox.isType = function(node) {
|
||||
MozMillCheckBox.isType = function (node) {
|
||||
if ((node.localName.toLowerCase() == "input" && node.getAttribute("type") == "checkbox") ||
|
||||
(node.localName.toLowerCase() == 'toolbarbutton' && node.getAttribute('type') == 'checkbox') ||
|
||||
(node.localName.toLowerCase() == 'checkbox')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable/Disable a checkbox depending on the target state
|
||||
*/
|
||||
MozMillCheckBox.prototype.check = function(state) {
|
||||
MozMillCheckBox.prototype.check = function (state) {
|
||||
var result = false;
|
||||
|
||||
if (!this.element) {
|
||||
throw new Error("could not find element " + this.getInfo());
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we have a XUL element, unwrap its XPCNativeWrapper
|
||||
if (this.element.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul") {
|
||||
if (this.element.namespaceURI == NAMESPACE_XUL) {
|
||||
this.element = utils.unwrapNode(this.element);
|
||||
}
|
||||
|
||||
|
@ -434,14 +436,16 @@ MozMillCheckBox.prototype.check = function(state) {
|
|||
if (state != this.element.checked) {
|
||||
this.click();
|
||||
var element = this.element;
|
||||
utils.waitFor(function() {
|
||||
|
||||
utils.waitFor(function () {
|
||||
return element.checked == state;
|
||||
}, "Checkbox " + this.getInfo() + " could not be checked/unchecked", 500);
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
broker.pass({'function':'MozMillCheckBox.check(' + this.getInfo() + ', state: ' + state + ')'});
|
||||
broker.pass({'function':'MozMillCheckBox.check(' + this.getInfo() +
|
||||
', state: ' + state + ')'});
|
||||
return result;
|
||||
};
|
||||
|
||||
|
@ -460,13 +464,14 @@ function MozMillRadio(locatorType, locator, args) {
|
|||
}
|
||||
|
||||
// Static method returns true if node is this type of element
|
||||
MozMillRadio.isType = function(node) {
|
||||
MozMillRadio.isType = function (node) {
|
||||
if ((node.localName.toLowerCase() == 'input' && node.getAttribute('type') == 'radio') ||
|
||||
(node.localName.toLowerCase() == 'toolbarbutton' && node.getAttribute('type') == 'radio') ||
|
||||
(node.localName.toLowerCase() == 'radio') ||
|
||||
(node.localName.toLowerCase() == 'radiogroup')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -476,7 +481,7 @@ MozMillRadio.isType = function(node) {
|
|||
* index - Specifies which radio button in the group to select (only applicable to radiogroup elements)
|
||||
* Defaults to the first radio button in the group
|
||||
*/
|
||||
MozMillRadio.prototype.select = function(index) {
|
||||
MozMillRadio.prototype.select = function (index) {
|
||||
if (!this.element) {
|
||||
throw new Error("could not find element " + this.getInfo());
|
||||
}
|
||||
|
@ -489,16 +494,18 @@ MozMillRadio.prototype.select = function(index) {
|
|||
this.click();
|
||||
}
|
||||
|
||||
utils.waitFor(function() {
|
||||
utils.waitFor(function () {
|
||||
// If we have a XUL element, unwrap its XPCNativeWrapper
|
||||
if (element.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul") {
|
||||
if (element.namespaceURI == NAMESPACE_XUL) {
|
||||
element = utils.unwrapNode(element);
|
||||
return element.selected == true;
|
||||
}
|
||||
|
||||
return element.checked == true;
|
||||
}, "Radio button " + this.getInfo() + " could not be selected", 500);
|
||||
|
||||
broker.pass({'function':'MozMillRadio.select(' + this.getInfo() + ')'});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -517,13 +524,14 @@ function MozMillDropList(locatorType, locator, args) {
|
|||
};
|
||||
|
||||
// Static method returns true if node is this type of element
|
||||
MozMillDropList.isType = function(node) {
|
||||
MozMillDropList.isType = function (node) {
|
||||
if ((node.localName.toLowerCase() == 'toolbarbutton' && (node.getAttribute('type') == 'menu' || node.getAttribute('type') == 'menu-button')) ||
|
||||
(node.localName.toLowerCase() == 'menu') ||
|
||||
(node.localName.toLowerCase() == 'menulist') ||
|
||||
(node.localName.toLowerCase() == 'select' )) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -546,6 +554,7 @@ MozMillDropList.prototype.select = function (indx, option, value) {
|
|||
this.dispatchEvent('change', true);
|
||||
|
||||
broker.pass({'function':'MozMillDropList.select()'});
|
||||
|
||||
return true;
|
||||
} else {
|
||||
item = this.element.options.item(indx);
|
||||
|
@ -569,14 +578,14 @@ MozMillDropList.prototype.select = function (indx, option, value) {
|
|||
this.dispatchEvent('change', true);
|
||||
|
||||
broker.pass({'function':'MozMillDropList.select()'});
|
||||
|
||||
return true;
|
||||
} catch (ex) {
|
||||
} catch (e) {
|
||||
throw new Error("No item selected for element " + this.getInfo());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//if we have a xul menupopup select accordingly
|
||||
else if (this.element.namespaceURI.toLowerCase() == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul") {
|
||||
else if (this.element.namespaceURI.toLowerCase() == NAMESPACE_XUL) {
|
||||
var ownerDoc = this.element.ownerDocument;
|
||||
// Unwrap the XUL element's XPCNativeWrapper
|
||||
this.element = utils.unwrapNode(this.element);
|
||||
|
@ -588,10 +597,11 @@ MozMillDropList.prototype.select = function (indx, option, value) {
|
|||
if (indx != undefined) {
|
||||
if (indx == -1) {
|
||||
this.dispatchEvent('focus', false);
|
||||
this.element.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject).activeChild = null;
|
||||
this.element.boxObject.QueryInterface(Ci.nsIMenuBoxObject).activeChild = null;
|
||||
this.dispatchEvent('change', true);
|
||||
|
||||
broker.pass({'function':'MozMillDropList.select()'});
|
||||
|
||||
return true;
|
||||
} else {
|
||||
item = menuitems[indx];
|
||||
|
@ -613,7 +623,7 @@ MozMillDropList.prototype.select = function (indx, option, value) {
|
|||
|
||||
// Scroll down until item is visible
|
||||
for (var i = 0; i <= menuitems.length; ++i) {
|
||||
var selected = this.element.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject).activeChild;
|
||||
var selected = this.element.boxObject.QueryInterface(Ci.nsIMenuBoxObject).activeChild;
|
||||
if (item == selected) {
|
||||
break;
|
||||
}
|
||||
|
@ -623,10 +633,10 @@ MozMillDropList.prototype.select = function (indx, option, value) {
|
|||
EventUtils.synthesizeMouse(item, 1, 1, {}, ownerDoc.defaultView);
|
||||
|
||||
broker.pass({'function':'MozMillDropList.select()'});
|
||||
|
||||
return true;
|
||||
} catch (ex) {
|
||||
} catch (e) {
|
||||
throw new Error('No item selected for element ' + this.getInfo());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -647,12 +657,13 @@ function MozMillTextBox(locatorType, locator, args) {
|
|||
};
|
||||
|
||||
// Static method returns true if node is this type of element
|
||||
MozMillTextBox.isType = function(node) {
|
||||
MozMillTextBox.isType = function (node) {
|
||||
if ((node.localName.toLowerCase() == 'input' && (node.getAttribute('type') == 'text' || node.getAttribute('type') == 'search')) ||
|
||||
(node.localName.toLowerCase() == 'textarea') ||
|
||||
(node.localName.toLowerCase() == 'textbox')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -685,19 +696,23 @@ MozMillTextBox.prototype.sendKeys = function (aText, aModifiers, aExpectedEvent)
|
|||
}
|
||||
|
||||
var element = this.element;
|
||||
Array.forEach(aText, function(letter) {
|
||||
var win = element.ownerDocument? element.ownerDocument.defaultView : element;
|
||||
Array.forEach(aText, function (letter) {
|
||||
var win = element.ownerDocument ? element.ownerDocument.defaultView
|
||||
: element;
|
||||
element.focus();
|
||||
|
||||
if (aExpectedEvent) {
|
||||
var target = aExpectedEvent.target ? aExpectedEvent.target.getNode() : element;
|
||||
EventUtils.synthesizeKeyExpectEvent(letter, aModifiers || {}, target, aExpectedEvent.type,
|
||||
"MozMillTextBox.sendKeys()", win);
|
||||
var target = aExpectedEvent.target ? aExpectedEvent.target.getNode()
|
||||
: element;
|
||||
EventUtils.synthesizeKeyExpectEvent(letter, aModifiers || {}, target,
|
||||
aExpectedEvent.type,
|
||||
"MozMillTextBox.sendKeys()", win);
|
||||
} else {
|
||||
EventUtils.synthesizeKey(letter, aModifiers || {}, win);
|
||||
}
|
||||
});
|
||||
|
||||
broker.pass({'function':'MozMillTextBox.type()'});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
|
|
@ -1,40 +1,6 @@
|
|||
// ***** 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 Mozilla Corporation Code.
|
||||
//
|
||||
// The Initial Developer of the Original Code is
|
||||
// Mikeal Rogers.
|
||||
// Portions created by the Initial Developer are Copyright (C) 2008
|
||||
// the Initial Developer. All Rights Reserved.
|
||||
//
|
||||
// Contributor(s):
|
||||
// Mikeal Rogers <mikeal.rogers@gmail.com>
|
||||
// Gary Kwong <nth10sd@gmail.com>
|
||||
//
|
||||
// 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 *****
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var EXPORTED_SYMBOLS = ["controller", "utils", "elementslib", "os",
|
||||
"getBrowserController", "newBrowserController",
|
||||
|
@ -46,55 +12,58 @@ var EXPORTED_SYMBOLS = ["controller", "utils", "elementslib", "os",
|
|||
"getPlacesController", 'isMac', 'isLinux', 'isWindows',
|
||||
"firePythonCallback"
|
||||
];
|
||||
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
// imports
|
||||
var controller = {}; Components.utils.import('resource://mozmill/driver/controller.js', controller);
|
||||
var elementslib = {}; Components.utils.import('resource://mozmill/driver/elementslib.js', elementslib);
|
||||
var broker = {}; Components.utils.import('resource://mozmill/driver/msgbroker.js', broker);
|
||||
var findElement = {}; Components.utils.import('resource://mozmill/driver/mozelement.js', findElement);
|
||||
var utils = {}; Components.utils.import('resource://mozmill/stdlib/utils.js', utils);
|
||||
var os = {}; Components.utils.import('resource://mozmill/stdlib/os.js', os);
|
||||
var controller = {}; Cu.import('resource://mozmill/driver/controller.js', controller);
|
||||
var elementslib = {}; Cu.import('resource://mozmill/driver/elementslib.js', elementslib);
|
||||
var broker = {}; Cu.import('resource://mozmill/driver/msgbroker.js', broker);
|
||||
var findElement = {}; Cu.import('resource://mozmill/driver/mozelement.js', findElement);
|
||||
var utils = {}; Cu.import('resource://mozmill/stdlib/utils.js', utils);
|
||||
var os = {}; Cu.import('resource://mozmill/stdlib/os.js', os);
|
||||
|
||||
try {
|
||||
Components.utils.import("resource://gre/modules/AddonManager.jsm");
|
||||
} catch(e) { /* Firefox 4 only */ }
|
||||
Cu.import("resource://gre/modules/AddonManager.jsm");
|
||||
} catch (e) {
|
||||
/* Firefox 4 only */
|
||||
}
|
||||
|
||||
// platform information
|
||||
var platform = os.getPlatform();
|
||||
var isMac = false;
|
||||
var isWindows = false;
|
||||
var isLinux = false;
|
||||
|
||||
if (platform == "darwin"){
|
||||
isMac = true;
|
||||
}
|
||||
|
||||
if (platform == "winnt"){
|
||||
isWindows = true;
|
||||
}
|
||||
|
||||
if (platform == "linux"){
|
||||
isLinux = true;
|
||||
}
|
||||
|
||||
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
|
||||
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Components.interfaces.nsIXULAppInfo);
|
||||
var aConsoleService = Cc["@mozilla.org/consoleservice;1"]
|
||||
.getService(Ci.nsIConsoleService);
|
||||
var appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
|
||||
var locale = Cc["@mozilla.org/chrome/chrome-registry;1"]
|
||||
.getService(Ci.nsIXULChromeRegistry)
|
||||
.getSelectedLocale("global");
|
||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
|
||||
|
||||
var locale = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
|
||||
.getService(Components.interfaces.nsIXULChromeRegistry)
|
||||
.getSelectedLocale("global");
|
||||
|
||||
var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"].
|
||||
getService(Components.interfaces.nsIConsoleService);
|
||||
|
||||
|
||||
applicationDictionary = {
|
||||
"{718e30fb-e89b-41dd-9da7-e25a45638b28}": "Sunbird",
|
||||
const applicationDictionary = {
|
||||
"{718e30fb-e89b-41dd-9da7-e25a45638b28}": "Sunbird",
|
||||
"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}": "SeaMonkey",
|
||||
"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}": "Firefox",
|
||||
"{3550f703-e582-4d05-9a08-453d09bdfdc6}": 'Thunderbird',
|
||||
}
|
||||
|
||||
"{3550f703-e582-4d05-9a08-453d09bdfdc6}": 'Thunderbird'
|
||||
};
|
||||
|
||||
var Application = applicationDictionary[appInfo.ID];
|
||||
|
||||
if (Application == undefined) {
|
||||
|
@ -106,43 +75,44 @@ if (Application == undefined) {
|
|||
// see http://blog.mozilla.com/tglek/2011/04/26/measuring-startup-speed-correctly/
|
||||
var startupInfo = {};
|
||||
try {
|
||||
var _startupInfo = Components.classes["@mozilla.org/toolkit/app-startup;1"]
|
||||
.getService(Components.interfaces.nsIAppStartup).getStartupInfo();
|
||||
for (var i in _startupInfo) {
|
||||
startupInfo[i] = _startupInfo[i].getTime(); // convert from Date object to ms since epoch
|
||||
}
|
||||
} catch(e) {
|
||||
startupInfo = null;
|
||||
var _startupInfo = Cc["@mozilla.org/toolkit/app-startup;1"]
|
||||
.getService(Ci.nsIAppStartup).getStartupInfo();
|
||||
for (var i in _startupInfo) {
|
||||
// convert from Date object to ms since epoch
|
||||
startupInfo[i] = _startupInfo[i].getTime();
|
||||
}
|
||||
} catch (e) {
|
||||
startupInfo = null;
|
||||
}
|
||||
|
||||
|
||||
// keep list of installed addons to send to jsbridge for test run report
|
||||
var addons = "null"; // this will be JSON parsed
|
||||
if(typeof AddonManager != "undefined") {
|
||||
AddonManager.getAllAddons(function(addonList) {
|
||||
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
|
||||
if (typeof AddonManager != "undefined") {
|
||||
AddonManager.getAllAddons(function (addonList) {
|
||||
var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = 'utf-8';
|
||||
|
||||
function replacer(key, value) {
|
||||
if (typeof(value) == "string") {
|
||||
try {
|
||||
return converter.ConvertToUnicode(value);
|
||||
} catch(e) {
|
||||
var newstring = '';
|
||||
for (var i=0; i < value.length; i++) {
|
||||
replacement = '';
|
||||
if ((32 <= value.charCodeAt(i)) && (value.charCodeAt(i) < 127)) {
|
||||
// eliminate non-convertable characters;
|
||||
newstring += value.charAt(i);
|
||||
} else {
|
||||
newstring += replacement;
|
||||
}
|
||||
}
|
||||
return newstring;
|
||||
if (typeof(value) == "string") {
|
||||
try {
|
||||
return converter.ConvertToUnicode(value);
|
||||
} catch (e) {
|
||||
var newstring = '';
|
||||
for (var i=0; i < value.length; i++) {
|
||||
replacement = '';
|
||||
if ((32 <= value.charCodeAt(i)) && (value.charCodeAt(i) < 127)) {
|
||||
// eliminate non-convertable characters;
|
||||
newstring += value.charAt(i);
|
||||
} else {
|
||||
newstring += replacement;
|
||||
}
|
||||
}
|
||||
return newstring;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
addons = converter.ConvertToUnicode(JSON.stringify(addonList, replacer))
|
||||
|
@ -163,34 +133,39 @@ function newBrowserController () {
|
|||
|
||||
function getBrowserController () {
|
||||
var browserWindow = wm.getMostRecentWindow("navigator:browser");
|
||||
|
||||
if (browserWindow == null) {
|
||||
return newBrowserController();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return new controller.MozMillController(browserWindow);
|
||||
}
|
||||
}
|
||||
|
||||
function getPlacesController () {
|
||||
utils.getMethodInWindows('PlacesCommandHook').showPlacesOrganizer('AllBookmarks');
|
||||
|
||||
return new controller.MozMillController(wm.getMostRecentWindow(''));
|
||||
}
|
||||
|
||||
function getAddonsController () {
|
||||
if (Application == 'SeaMonkey') {
|
||||
utils.getMethodInWindows('toEM')();
|
||||
} else if (Application == 'Thunderbird') {
|
||||
}
|
||||
else if (Application == 'Thunderbird') {
|
||||
utils.getMethodInWindows('openAddonsMgr')();
|
||||
} else if (Application == 'Sunbird') {
|
||||
}
|
||||
else if (Application == 'Sunbird') {
|
||||
utils.getMethodInWindows('goOpenAddons')();
|
||||
} else {
|
||||
utils.getMethodInWindows('BrowserOpenAddonsMgr')();
|
||||
}
|
||||
|
||||
return new controller.MozMillController(wm.getMostRecentWindow(''));
|
||||
}
|
||||
|
||||
function getDownloadsController() {
|
||||
utils.getMethodInWindows('BrowserDownloadsUI')();
|
||||
|
||||
return new controller.MozMillController(wm.getMostRecentWindow(''));
|
||||
}
|
||||
|
||||
|
@ -200,6 +175,7 @@ function getPreferencesController() {
|
|||
} else {
|
||||
utils.getMethodInWindows('openPreferences')();
|
||||
}
|
||||
|
||||
return new controller.MozMillController(wm.getMostRecentWindow(''));
|
||||
}
|
||||
|
||||
|
@ -210,10 +186,10 @@ function newMail3PaneController () {
|
|||
|
||||
function getMail3PaneController () {
|
||||
var mail3PaneWindow = wm.getMostRecentWindow("mail:3pane");
|
||||
|
||||
if (mail3PaneWindow == null) {
|
||||
return newMail3PaneController();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return new controller.MozMillController(mail3PaneWindow);
|
||||
}
|
||||
}
|
||||
|
@ -223,6 +199,7 @@ function newAddrbkController () {
|
|||
utils.getMethodInWindows("toAddressBook")();
|
||||
utils.sleep(2000);
|
||||
var addyWin = wm.getMostRecentWindow("mail:addressbook");
|
||||
|
||||
return new controller.MozMillController(addyWin);
|
||||
}
|
||||
|
||||
|
@ -230,8 +207,7 @@ function getAddrbkController () {
|
|||
var addrbkWindow = wm.getMostRecentWindow("mail:addressbook");
|
||||
if (addrbkWindow == null) {
|
||||
return newAddrbkController();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return new controller.MozMillController(addrbkWindow);
|
||||
}
|
||||
}
|
||||
|
@ -240,23 +216,29 @@ function firePythonCallback (filename, method, args, kwargs) {
|
|||
obj = {'filename': filename, 'method': method};
|
||||
obj['args'] = args || [];
|
||||
obj['kwargs'] = kwargs || {};
|
||||
|
||||
broker.sendMessage("firePythonCallback", obj);
|
||||
}
|
||||
|
||||
function timer (name) {
|
||||
this.name = name;
|
||||
this.timers = {};
|
||||
frame.timers.push(this);
|
||||
this.actions = [];
|
||||
|
||||
frame.timers.push(this);
|
||||
}
|
||||
|
||||
timer.prototype.start = function (name) {
|
||||
this.timers[name].startTime = (new Date).getTime();
|
||||
}
|
||||
}
|
||||
|
||||
timer.prototype.stop = function (name) {
|
||||
var t = this.timers[name];
|
||||
|
||||
t.endTime = (new Date).getTime();
|
||||
t.totalTime = (t.endTime - t.startTime);
|
||||
}
|
||||
|
||||
timer.prototype.end = function () {
|
||||
frame.events.fireEvent("timer", this);
|
||||
frame.timers.remove(this);
|
||||
|
@ -271,63 +253,83 @@ timer.prototype.end = function () {
|
|||
function ConsoleListener() {
|
||||
this.register();
|
||||
}
|
||||
|
||||
ConsoleListener.prototype = {
|
||||
observe: function(aMessage) {
|
||||
var msg = aMessage.message;
|
||||
var re = /^\[.*Error:.*(chrome|resource):\/\/.*/i;
|
||||
if (msg.match(re)) {
|
||||
broker.fail(aMessage);
|
||||
}
|
||||
},
|
||||
QueryInterface: function (iid) {
|
||||
if (!iid.equals(Components.interfaces.nsIConsoleListener) && !iid.equals(Components.interfaces.nsISupports)) {
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
register: function() {
|
||||
var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"]
|
||||
.getService(Components.interfaces.nsIConsoleService);
|
||||
aConsoleService.registerListener(this);
|
||||
},
|
||||
unregister: function() {
|
||||
var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"]
|
||||
.getService(Components.interfaces.nsIConsoleService);
|
||||
aConsoleService.unregisterListener(this);
|
||||
observe: function (aMessage) {
|
||||
var msg = aMessage.message;
|
||||
var re = /^\[.*Error:.*(chrome|resource):\/\/.*/i;
|
||||
if (msg.match(re)) {
|
||||
broker.fail(aMessage);
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: function (iid) {
|
||||
if (!iid.equals(Ci.nsIConsoleListener) && !iid.equals(Ci.nsISupports)) {
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
register: function () {
|
||||
var aConsoleService = Cc["@mozilla.org/consoleservice;1"]
|
||||
.getService(Ci.nsIConsoleService);
|
||||
aConsoleService.registerListener(this);
|
||||
},
|
||||
|
||||
unregister: function () {
|
||||
var aConsoleService = Cc["@mozilla.org/consoleservice;1"]
|
||||
.getService(Ci.nsIConsoleService);
|
||||
aConsoleService.unregisterListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
// start listening
|
||||
var consoleListener = new ConsoleListener();
|
||||
|
||||
// Observer for new top level windows
|
||||
var windowObserver = {
|
||||
observe: function(subject, topic, data) {
|
||||
attachEventListeners(subject);
|
||||
|
||||
|
||||
// Observer when a new top-level window is ready
|
||||
var windowReadyObserver = {
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
attachEventListeners(aSubject);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Observer when a top-level window is closed
|
||||
var windowCloseObserver = {
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
controller.windowMap.remove(utils.getWindowId(aSubject));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Attach event listeners
|
||||
*
|
||||
* @param {ChromeWindow} aWindow
|
||||
* Window to attach listeners on.
|
||||
*/
|
||||
function attachEventListeners(aWindow) {
|
||||
// These are the event handlers
|
||||
function pageShowHandler(event) {
|
||||
var doc = event.originalTarget;
|
||||
var pageShowHandler = function (aEvent) {
|
||||
var doc = aEvent.originalTarget;
|
||||
|
||||
// Only update the flag if we have a document as target
|
||||
// see https://bugzilla.mozilla.org/show_bug.cgi?id=690829
|
||||
if ("defaultView" in doc) {
|
||||
doc.defaultView.mozmillDocumentLoaded = true;
|
||||
var id = utils.getWindowId(doc.defaultView);
|
||||
controller.windowMap.update(id, "loaded", true);
|
||||
//dump("*** pageshow event: " + id + ", " + doc.location + ", baseURI=" + doc.baseURI + "\n");
|
||||
}
|
||||
|
||||
// We need to add/remove the unload/pagehide event listeners to preserve caching.
|
||||
aWindow.gBrowser.addEventListener("beforeunload", beforeUnloadHandler, true);
|
||||
aWindow.gBrowser.addEventListener("pagehide", pageHideHandler, true);
|
||||
aWindow.getBrowser().addEventListener("beforeunload", beforeUnloadHandler, true);
|
||||
aWindow.getBrowser().addEventListener("pagehide", pageHideHandler, true);
|
||||
};
|
||||
|
||||
function DOMContentLoadedHandler(event) {
|
||||
var doc = event.originalTarget;
|
||||
var DOMContentLoadedHandler = function (aEvent) {
|
||||
var doc = aEvent.originalTarget;
|
||||
|
||||
var errorRegex = /about:.+(error)|(blocked)\?/;
|
||||
if (errorRegex.exec(doc.baseURI)) {
|
||||
|
@ -336,60 +338,65 @@ function attachEventListeners(aWindow) {
|
|||
|
||||
// Only update the flag if we have a document as target
|
||||
if ("defaultView" in doc) {
|
||||
doc.defaultView.mozmillDocumentLoaded = true;
|
||||
var id = utils.getWindowId(doc.defaultView);
|
||||
controller.windowMap.update(id, "loaded", true);
|
||||
//dump("*** DOMContentLoaded event: " + id + ", " + doc.location + ", baseURI=" + doc.baseURI + "\n");
|
||||
}
|
||||
|
||||
// We need to add/remove the unload event listener to preserve caching.
|
||||
aWindow.gBrowser.addEventListener("beforeunload", beforeUnloadHandler, true);
|
||||
aWindow.getBrowser().addEventListener("beforeunload", beforeUnloadHandler, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// beforeunload is still needed because pagehide doesn't fire before the page is unloaded.
|
||||
// still use pagehide for cases when beforeunload doesn't get fired
|
||||
function beforeUnloadHandler(event) {
|
||||
var doc = event.originalTarget;
|
||||
var beforeUnloadHandler = function (aEvent) {
|
||||
var doc = aEvent.originalTarget;
|
||||
|
||||
// Only update the flag if we have a document as target
|
||||
if ("defaultView" in doc) {
|
||||
doc.defaultView.mozmillDocumentLoaded = false;
|
||||
var id = utils.getWindowId(doc.defaultView);
|
||||
controller.windowMap.update(id, "loaded", false);
|
||||
//dump("*** beforeunload event: " + id + ", " + doc.location + ", baseURI=" + doc.baseURI + "\n");
|
||||
}
|
||||
|
||||
aWindow.gBrowser.removeEventListener("beforeunload", beforeUnloadHandler, true);
|
||||
aWindow.getBrowser().removeEventListener("beforeunload", beforeUnloadHandler, true);
|
||||
};
|
||||
|
||||
function pageHideHandler(event) {
|
||||
var pageHideHandler = function (aEvent) {
|
||||
// If event.persisted is false, the beforeUnloadHandler should fire
|
||||
// and there is no need for this event handler.
|
||||
if (event.persisted) {
|
||||
var doc = event.originalTarget;
|
||||
if (aEvent.persisted) {
|
||||
var doc = aEvent.originalTarget;
|
||||
|
||||
// Only update the flag if we have a document as target
|
||||
if ("defaultView" in doc) {
|
||||
doc.defaultView.mozmillDocumentLoaded = false;
|
||||
var id = utils.getWindowId(doc.defaultView);
|
||||
controller.windowMap.update(id, "loaded", false);
|
||||
//dump("*** pagehide event: " + id + ", " + doc.location + ", baseURI=" + doc.baseURI + "\n");
|
||||
}
|
||||
|
||||
aWindow.gBrowser.removeEventListener("beforeunload", beforeUnloadHandler, true);
|
||||
aWindow.getBrowser().removeEventListener("beforeunload", beforeUnloadHandler, true);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function onWindowLoaded(event) {
|
||||
aWindow.mozmillDocumentLoaded = true;
|
||||
var onWindowLoaded = function (aEvent) {
|
||||
controller.windowMap.update(utils.getWindowId(aWindow), "loaded", true);
|
||||
|
||||
if ("gBrowser" in aWindow) {
|
||||
let browser = aWindow.getBrowser();
|
||||
if (browser) {
|
||||
// Page is ready
|
||||
aWindow.gBrowser.addEventListener("pageshow", pageShowHandler, true);
|
||||
browser.addEventListener("pageshow", pageShowHandler, true);
|
||||
|
||||
// Note: Error pages will never fire a "load" event. For those we
|
||||
// Note: Error pages will never fire a "pageshow" event. For those we
|
||||
// have to wait for the "DOMContentLoaded" event. That's the final state.
|
||||
// Error pages will always have a baseURI starting with
|
||||
// "about:" followed by "error" or "blocked".
|
||||
aWindow.gBrowser.addEventListener("DOMContentLoaded", DOMContentLoadedHandler, true);
|
||||
|
||||
// Leave page (use caching)
|
||||
aWindow.gBrowser.addEventListener("pagehide", pageHideHandler, true);
|
||||
}
|
||||
browser.addEventListener("DOMContentLoaded", DOMContentLoadedHandler, true);
|
||||
|
||||
// Leave page (use caching)
|
||||
browser.addEventListener("pagehide", pageHideHandler, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the event handlers to the tabbedbrowser once its window has loaded
|
||||
|
@ -399,28 +406,29 @@ function attachEventListeners(aWindow) {
|
|||
aWindow.addEventListener("load", onWindowLoaded, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize Mozmill
|
||||
*/
|
||||
function initialize() {
|
||||
// Activate observer for new top level windows
|
||||
var observerService = Components.classes["@mozilla.org/observer-service;1"].
|
||||
getService(Components.interfaces.nsIObserverService);
|
||||
observerService.addObserver(windowObserver, "toplevel-window-ready", false);
|
||||
var observerService = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
observerService.addObserver(windowReadyObserver, "toplevel-window-ready", false);
|
||||
observerService.addObserver(windowCloseObserver, "outer-window-destroyed", false);
|
||||
|
||||
// Attach event listeners to all open windows
|
||||
var enumerator = Components.classes["@mozilla.org/appshell/window-mediator;1"].
|
||||
getService(Components.interfaces.nsIWindowMediator).getEnumerator("");
|
||||
var enumerator = Cc["@mozilla.org/appshell/window-mediator;1"].
|
||||
getService(Ci.nsIWindowMediator).getEnumerator("");
|
||||
while (enumerator.hasMoreElements()) {
|
||||
var win = enumerator.getNext();
|
||||
attachEventListeners(win);
|
||||
|
||||
// For windows or dialogs already open we have to explicitly set the property
|
||||
// otherwise windows which load really quick never gets the property set and
|
||||
// we fail to create the controller
|
||||
win.mozmillDocumentLoaded = true;
|
||||
};
|
||||
// otherwise windows which load really quick on startup never gets the
|
||||
// property set and we fail to create the controller
|
||||
controller.windowMap.update(utils.getWindowId(win), "loaded", true);
|
||||
}
|
||||
}
|
||||
|
||||
initialize();
|
||||
|
|
|
@ -1,40 +1,6 @@
|
|||
/* ***** 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.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Andrew Halberstadt <halbersa@gmail.com>
|
||||
*
|
||||
* 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 ***** */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var EXPORTED_SYMBOLS = ['addListener', 'addObject',
|
||||
'removeListener',
|
||||
|
@ -44,10 +10,10 @@ var listeners = {};
|
|||
|
||||
// add a listener for a specific message type
|
||||
function addListener(msgType, listener) {
|
||||
|
||||
if (listeners[msgType] === undefined) {
|
||||
listeners[msgType] = [];
|
||||
}
|
||||
|
||||
listeners[msgType].push(listener);
|
||||
}
|
||||
|
||||
|
@ -73,6 +39,7 @@ function sendMessage(msgType, obj) {
|
|||
if (listeners[msgType] === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < listeners[msgType].length; ++i) {
|
||||
listeners[msgType][i](obj);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ var EXPORTED_SYMBOLS = ["sendMouseEvent", "sendChar", "sendString", "sendKey",
|
|||
"synthesizeMouse", "synthesizeMouseScroll", "synthesizeKey",
|
||||
"synthesizeMouseExpectEvent", "synthesizeKeyExpectEvent",
|
||||
"synthesizeDragStart", "synthesizeDrop", "synthesizeText",
|
||||
"disableNonTestMouseEvents", "synthesizeComposition",
|
||||
"disableNonTestMouseEvents", "synthesizeComposition",
|
||||
"synthesizeQuerySelectedText", "synthesizeQueryTextContent",
|
||||
"synthesizeQueryCaretRect", "synthesizeQueryTextRect",
|
||||
"synthesizeQueryEditorRect", "synthesizeCharAtPoint",
|
||||
|
@ -37,7 +37,7 @@ function getKeyEvent(aWindow) {
|
|||
*/
|
||||
function sendMouseEvent(aEvent, aTarget, aWindow) {
|
||||
if (['click', 'mousedown', 'mouseup', 'mouseover', 'mouseout'].indexOf(aEvent.type) == -1) {
|
||||
throw new Error("sendMouseEvent doesn't know about event type '"+aEvent.type+"'");
|
||||
throw new Error("sendMouseEvent doesn't know about event type '" + aEvent.type + "'");
|
||||
}
|
||||
|
||||
if (!aWindow) {
|
||||
|
@ -116,9 +116,10 @@ function sendString(aStr, aTarget) {
|
|||
|
||||
/**
|
||||
* Send the non-character key aKey to the node with id aTarget. If aTarget is
|
||||
* not provided, use "target". The name of the key should be a lowercase
|
||||
* version of the part that comes after "DOM_VK_" in the KeyEvent constant
|
||||
* name for this key. No modifiers are handled at this point.
|
||||
* not provided, use "target".
|
||||
* The name of the key should be the part that comes after "DOM_VK_" in the
|
||||
* KeyEvent constant name for this key.
|
||||
* No modifiers are handled at this point.
|
||||
*
|
||||
* Returns true if the keypress event was accepted (no calls to preventDefault
|
||||
* or anything like that), false otherwise.
|
||||
|
@ -127,7 +128,7 @@ function sendKey(aKey, aTarget, aWindow) {
|
|||
if (!aWindow)
|
||||
aWindow = window;
|
||||
|
||||
keyName = "DOM_VK_" + aKey.toUpperCase();
|
||||
var keyName = "DOM_VK_" + aKey.toUpperCase();
|
||||
|
||||
if (!getKeyEvent(aWindow)[keyName]) {
|
||||
throw "Unknown key: " + keyName;
|
||||
|
@ -238,7 +239,7 @@ function synthesizeMouse(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
|
|||
var left = rect.left + aOffsetX;
|
||||
var top = rect.top + aOffsetY;
|
||||
|
||||
if (aEvent.type) {
|
||||
if (("type" in aEvent) && aEvent.type) {
|
||||
utils.sendMouseEvent(aEvent.type, left, top, button, clickCount, modifiers);
|
||||
}
|
||||
else {
|
||||
|
@ -290,7 +291,7 @@ function synthesizeMouseScroll(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
|
|||
var left = rect.left;
|
||||
var top = rect.top;
|
||||
|
||||
var type = aEvent.type || "DOMMouseScroll";
|
||||
var type = (("type" in aEvent) && aEvent.type) || "DOMMouseScroll";
|
||||
var axis = aEvent.axis || "vertical";
|
||||
var scrollFlags = (axis == "horizontal") ? kIsHorizontal : kIsVertical;
|
||||
if (aEvent.hasPixels) {
|
||||
|
@ -332,15 +333,16 @@ function synthesizeKey(aKey, aEvent, aWindow)
|
|||
|
||||
var modifiers = _parseModifiers(aEvent);
|
||||
|
||||
if (aEvent.type) {
|
||||
utils.sendKeyEvent(aEvent.type, keyCode, charCode, modifiers);
|
||||
}
|
||||
else {
|
||||
if (!("type" in aEvent) || !aEvent.type) {
|
||||
// Send keydown + keypress + keyup events.
|
||||
var keyDownDefaultHappened =
|
||||
utils.sendKeyEvent("keydown", keyCode, charCode, modifiers);
|
||||
utils.sendKeyEvent("keypress", keyCode, charCode, modifiers,
|
||||
!keyDownDefaultHappened);
|
||||
utils.sendKeyEvent("keyup", keyCode, charCode, modifiers);
|
||||
} else {
|
||||
// Send standalone event.
|
||||
utils.sendKeyEvent(aEvent.type, keyCode, charCode, modifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -700,6 +702,7 @@ function synthesizeQuerySelectedText(aWindow)
|
|||
if (!utils) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return utils.sendQueryContentEvent(utils.QUERY_SELECTED_TEXT, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
@ -720,6 +723,7 @@ function synthesizeQueryTextContent(aOffset, aLength, aWindow)
|
|||
if (!utils) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return utils.sendQueryContentEvent(utils.QUERY_TEXT_CONTENT,
|
||||
aOffset, aLength, 0, 0);
|
||||
}
|
||||
|
@ -739,6 +743,7 @@ function synthesizeQueryCaretRect(aOffset, aWindow)
|
|||
if (!utils) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return utils.sendQueryContentEvent(utils.QUERY_CARET_RECT,
|
||||
aOffset, 0, 0, 0);
|
||||
}
|
||||
|
@ -760,6 +765,7 @@ function synthesizeQueryTextRect(aOffset, aLength, aWindow)
|
|||
if (!utils) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return utils.sendQueryContentEvent(utils.QUERY_TEXT_RECT,
|
||||
aOffset, aLength, 0, 0);
|
||||
}
|
||||
|
@ -777,6 +783,7 @@ function synthesizeQueryEditorRect(aWindow)
|
|||
if (!utils) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return utils.sendQueryContentEvent(utils.QUERY_EDITOR_RECT, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
@ -794,6 +801,7 @@ function synthesizeCharAtPoint(aX, aY, aWindow)
|
|||
if (!utils) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return utils.sendQueryContentEvent(utils.QUERY_CHARACTER_AT_POINT,
|
||||
0, 0, aX, aY);
|
||||
}
|
||||
|
@ -816,5 +824,6 @@ function synthesizeSelectionSet(aOffset, aLength, aReverse, aWindow)
|
|||
if (!utils) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return utils.sendSelectionSetEvent(aOffset, aLength, aReverse);
|
||||
}
|
||||
|
|
|
@ -1,82 +1,56 @@
|
|||
// ***** BEGIN LICENSE BLOCK *****// ***** 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 Mozilla Corporation Code.
|
||||
//
|
||||
// The Initial Developer of the Original Code is
|
||||
// Mikeal Rogers.
|
||||
// Portions created by the Initial Developer are Copyright (C) 2008
|
||||
// the Initial Developer. All Rights Reserved.
|
||||
//
|
||||
// Contributor(s):
|
||||
// Mikeal Rogers <mikeal.rogers@gmail.com>
|
||||
//
|
||||
// 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 *****
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var EXPORTED_SYMBOLS = ['inArray', 'getSet', 'indexOf', 'rindexOf', 'compare'];
|
||||
|
||||
function inArray (array, value) {
|
||||
for (i in array) {
|
||||
function inArray(array, value) {
|
||||
for (var i in array) {
|
||||
if (value == array[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getSet (array) {
|
||||
function getSet(array) {
|
||||
var narray = [];
|
||||
for (i in array) {
|
||||
if ( !inArray(narray, array[i]) ) {
|
||||
|
||||
for (var i in array) {
|
||||
if (!inArray(narray, array[i])) {
|
||||
narray.push(array[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return narray;
|
||||
}
|
||||
|
||||
function indexOf (array, v, offset) {
|
||||
for (i in array) {
|
||||
function indexOf(array, v, offset) {
|
||||
for (var i in array) {
|
||||
if (offset == undefined || i >= offset) {
|
||||
if ( !isNaN(i) && array[i] == v) {
|
||||
if (!isNaN(i) && array[i] == v) {
|
||||
return new Number(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function rindexOf (array, v) {
|
||||
var l = array.length;
|
||||
for (i in array) {
|
||||
|
||||
for (var i in array) {
|
||||
if (!isNaN(i)) {
|
||||
var i = new Number(i)
|
||||
var i = new Number(i);
|
||||
}
|
||||
|
||||
if (!isNaN(i) && array[l - i] == v) {
|
||||
return l - i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -84,10 +58,12 @@ function compare (array, carray) {
|
|||
if (array.length != carray.length) {
|
||||
return false;
|
||||
}
|
||||
for (i in array) {
|
||||
|
||||
for (var i in array) {
|
||||
if (array[i] != carray[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,54 +1,24 @@
|
|||
// ***** BEGIN LICENSE BLOCK *****// ***** 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 Mozilla Corporation Code.
|
||||
//
|
||||
// The Initial Developer of the Original Code is
|
||||
// Mikeal Rogers.
|
||||
// Portions created by the Initial Developer are Copyright (C) 2008
|
||||
// the Initial Developer. All Rights Reserved.
|
||||
//
|
||||
// Contributor(s):
|
||||
// Mikeal Rogers <mikeal.rogers@gmail.com>
|
||||
//
|
||||
// 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 *****
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var EXPORTED_SYMBOLS = ['getAttributes'];
|
||||
|
||||
|
||||
var getAttributes = function (node) {
|
||||
var attributes = {};
|
||||
for (i in node.attributes) {
|
||||
if ( !isNaN(i) ) {
|
||||
|
||||
for (var i in node.attributes) {
|
||||
if (!isNaN(i)) {
|
||||
try {
|
||||
var attr = node.attributes[i];
|
||||
attributes[attr.name] = attr.value;
|
||||
} catch (err) {
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,39 +1,6 @@
|
|||
// ***** BEGIN LICENSE BLOCK *****// ***** 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 Mozilla Corporation Code.
|
||||
//
|
||||
// The Initial Developer of the Original Code is
|
||||
// Mikeal Rogers.
|
||||
// Portions created by the Initial Developer are Copyright (C) 2008
|
||||
// the Initial Developer. All Rights Reserved.
|
||||
//
|
||||
// Contributor(s):
|
||||
// Mikeal Rogers <mikeal.rogers@gmail.com>
|
||||
//
|
||||
// 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 *****
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var EXPORTED_SYMBOLS = ['getLength', ];//'compare'];
|
||||
|
||||
|
@ -42,6 +9,7 @@ var getLength = function (obj) {
|
|||
for (i in obj) {
|
||||
len++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,71 +1,43 @@
|
|||
// ***** BEGIN LICENSE BLOCK *****// ***** 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 Mozilla Corporation Code.
|
||||
//
|
||||
// The Initial Developer of the Original Code is
|
||||
// Mikeal Rogers.
|
||||
// Portions created by the Initial Developer are Copyright (C) 2008
|
||||
// the Initial Developer. All Rights Reserved.
|
||||
//
|
||||
// Contributor(s):
|
||||
// Mikeal Rogers <mikeal.rogers@gmail.com>
|
||||
//
|
||||
// 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 *****
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var EXPORTED_SYMBOLS = ['listDirectory', 'getFileForPath', 'abspath', 'getPlatform'];
|
||||
|
||||
function listDirectory (file) {
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
function listDirectory(file) {
|
||||
// file is the given directory (nsIFile)
|
||||
var entries = file.directoryEntries;
|
||||
var array = [];
|
||||
while (entries.hasMoreElements())
|
||||
{
|
||||
|
||||
while (entries.hasMoreElements()) {
|
||||
var entry = entries.getNext();
|
||||
entry.QueryInterface(Components.interfaces.nsIFile);
|
||||
entry.QueryInterface(Ci.nsIFile);
|
||||
array.push(entry);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
function getFileForPath (path) {
|
||||
var file = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
function getFileForPath(path) {
|
||||
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
file.initWithPath(path);
|
||||
return file;
|
||||
}
|
||||
|
||||
function abspath (rel, file) {
|
||||
function abspath(rel, file) {
|
||||
var relSplit = rel.split('/');
|
||||
|
||||
if (relSplit[0] == '..' && !file.isDirectory()) {
|
||||
file = file.parent;
|
||||
}
|
||||
for each(p in relSplit) {
|
||||
|
||||
for each(var p in relSplit) {
|
||||
if (p == '..') {
|
||||
file = file.parent;
|
||||
} else if (p == '.'){
|
||||
} else if (p == '.') {
|
||||
if (!file.isDirectory()) {
|
||||
file = file.parent;
|
||||
}
|
||||
|
@ -73,14 +45,13 @@ function abspath (rel, file) {
|
|||
file.append(p);
|
||||
}
|
||||
}
|
||||
|
||||
return file.path;
|
||||
}
|
||||
|
||||
function getPlatform () {
|
||||
var xulRuntime = Components.classes["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Components.interfaces.nsIXULRuntime);
|
||||
function getPlatform() {
|
||||
var xulRuntime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
|
||||
mPlatform = xulRuntime.OS.toLowerCase();
|
||||
|
||||
return mPlatform;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,39 +1,6 @@
|
|||
// ***** BEGIN LICENSE BLOCK *****// ***** 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 Mozilla Corporation Code.
|
||||
//
|
||||
// The Initial Developer of the Original Code is
|
||||
// Mikeal Rogers.
|
||||
// Portions created by the Initial Developer are Copyright (C) 2008
|
||||
// the Initial Developer. All Rights Reserved.
|
||||
//
|
||||
// Contributor(s):
|
||||
// Mikeal Rogers <mikeal.rogers@gmail.com>
|
||||
//
|
||||
// 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 *****
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var EXPORTED_SYMBOLS = ['trim', 'vslice'];
|
||||
|
||||
|
@ -47,4 +14,4 @@ var vslice = function (str, svalue, evalue) {
|
|||
var sindex = arrays.indexOf(str, svalue);
|
||||
var eindex = arrays.rindexOf(str, evalue);
|
||||
return str.slice(sindex + 1, eindex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,56 +1,23 @@
|
|||
// ***** 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 Mozilla Corporation Code.
|
||||
//
|
||||
// The Initial Developer of the Original Code is
|
||||
// Adam Christian.
|
||||
// Portions created by the Initial Developer are Copyright (C) 2008
|
||||
// the Initial Developer. All Rights Reserved.
|
||||
//
|
||||
// Contributor(s):
|
||||
// Adam Christian <adam.christian@gmail.com>
|
||||
// Mikeal Rogers <mikeal.rogers@gmail.com>
|
||||
// Henrik Skupin <hskupin@mozilla.com>
|
||||
//
|
||||
// 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 *****
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var EXPORTED_SYMBOLS = ["openFile", "saveFile", "saveAsFile", "genBoiler",
|
||||
"getFile", "Copy", "getChromeWindow", "getWindows", "runEditor",
|
||||
"runFile", "getWindowByTitle", "getWindowByType", "tempfile",
|
||||
"getMethodInWindows", "getPreference", "setPreference",
|
||||
"runFile", "getWindowByTitle", "getWindowByType", "getWindowId",
|
||||
"tempfile", "getMethodInWindows", "getPreference", "setPreference",
|
||||
"sleep", "assert", "unwrapNode", "TimeoutError", "waitFor",
|
||||
"takeScreenshot",
|
||||
];
|
||||
|
||||
var hwindow = Components.classes["@mozilla.org/appshell/appShellService;1"]
|
||||
.getService(Components.interfaces.nsIAppShellService)
|
||||
.hiddenDOMWindow;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
var uuidgen = Components.classes["@mozilla.org/uuid-generator;1"]
|
||||
.getService(Components.interfaces.nsIUUIDGenerator);
|
||||
var hwindow = Cc["@mozilla.org/appshell/appShellService;1"]
|
||||
.getService(Ci.nsIAppShellService).hiddenDOMWindow;
|
||||
|
||||
var uuidgen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
|
||||
|
||||
function Copy (obj) {
|
||||
for (var n in obj) {
|
||||
|
@ -59,206 +26,227 @@ function Copy (obj) {
|
|||
}
|
||||
|
||||
function getChromeWindow(aWindow) {
|
||||
var chromeWin = aWindow
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindow)
|
||||
.QueryInterface(Components.interfaces.nsIDOMChromeWindow);
|
||||
var chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow)
|
||||
.QueryInterface(Ci.nsIDOMChromeWindow);
|
||||
|
||||
return chromeWin;
|
||||
}
|
||||
|
||||
function getWindows(type) {
|
||||
if (type == undefined) {
|
||||
type = "";
|
||||
type = "";
|
||||
}
|
||||
var windows = []
|
||||
var enumerator = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Components.interfaces.nsIWindowMediator)
|
||||
.getEnumerator(type);
|
||||
while(enumerator.hasMoreElements()) {
|
||||
|
||||
var windows = [];
|
||||
var enumerator = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Ci.nsIWindowMediator).getEnumerator(type);
|
||||
|
||||
while (enumerator.hasMoreElements()) {
|
||||
windows.push(enumerator.getNext());
|
||||
}
|
||||
|
||||
if (type == "") {
|
||||
windows.push(hwindow);
|
||||
}
|
||||
|
||||
return windows;
|
||||
}
|
||||
|
||||
function getMethodInWindows (methodName) {
|
||||
for each(w in getWindows()) {
|
||||
function getMethodInWindows(methodName) {
|
||||
for each (var w in getWindows()) {
|
||||
if (w[methodName] != undefined) {
|
||||
return w[methodName];
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error("Method with name: '" + methodName + "' is not in any open window.");
|
||||
}
|
||||
|
||||
function getWindowByTitle(title) {
|
||||
for each(w in getWindows()) {
|
||||
for each (var w in getWindows()) {
|
||||
if (w.document.title && w.document.title == title) {
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error("Window with title: '" + title + "' not found.");
|
||||
}
|
||||
|
||||
function getWindowByType(type) {
|
||||
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Ci.nsIWindowMediator);
|
||||
|
||||
return wm.getMostRecentWindow(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the outer window id for the given window.
|
||||
*
|
||||
* @param {Number} aWindow
|
||||
* Window to retrieve the id from.
|
||||
* @returns {Boolean} The outer window id
|
||||
**/
|
||||
function getWindowId(aWindow) {
|
||||
try {
|
||||
// Normally we can retrieve the id via window utils
|
||||
return aWindow.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDOMWindowUtils).
|
||||
outerWindowID;
|
||||
} catch (e) {
|
||||
// ... but for observer notifications we need another interface
|
||||
return aWindow.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
}
|
||||
}
|
||||
|
||||
function tempfile(appention) {
|
||||
if (appention == undefined) {
|
||||
var appention = "mozmill.utils.tempfile"
|
||||
appention = "mozmill.utils.tempfile";
|
||||
}
|
||||
var tempfile = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("TmpD", Components.interfaces.nsIFile);
|
||||
tempfile.append(uuidgen.generateUUID().toString().replace('-', '').replace('{', '').replace('}',''))
|
||||
tempfile.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
|
||||
tempfile.append(appention);
|
||||
tempfile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
|
||||
// do whatever you need to the created file
|
||||
return tempfile.clone()
|
||||
|
||||
var tempfile = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
|
||||
tempfile.append(uuidgen.generateUUID().toString().replace('-', '')
|
||||
.replace('{', '')
|
||||
.replace('}',''));
|
||||
tempfile.create(Ci.nsIFile.DIRECTORY_TYPE, 0777);
|
||||
tempfile.append(appention);
|
||||
tempfile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
|
||||
// do whatever you need to the created file
|
||||
|
||||
return tempfile.clone();
|
||||
}
|
||||
|
||||
var checkChrome = function() {
|
||||
var loc = window.document.location.href;
|
||||
try {
|
||||
loc = window.top.document.location.href;
|
||||
} catch (e) {}
|
||||
var checkChrome = function () {
|
||||
var loc = window.document.location.href;
|
||||
try {
|
||||
loc = window.top.document.location.href;
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (/^chrome:\/\//.test(loc)) { return true; }
|
||||
else { return false; }
|
||||
return /^chrome:\/\//.test(loc);
|
||||
}
|
||||
|
||||
|
||||
var runFile = function(w){
|
||||
//define the interface
|
||||
var nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||
//define the file picker window
|
||||
fp.init(w, "Select a File", nsIFilePicker.modeOpen);
|
||||
fp.appendFilter("JavaScript Files","*.js");
|
||||
//show the window
|
||||
var res = fp.show();
|
||||
//if we got a file
|
||||
if (res == nsIFilePicker.returnOK){
|
||||
var thefile = fp.file;
|
||||
//create the paramObj with a files array attrib
|
||||
var paramObj = {};
|
||||
paramObj.files = [];
|
||||
paramObj.files.push(thefile.path);
|
||||
}
|
||||
};
|
||||
|
||||
var saveFile = function(w, content, filename){
|
||||
//define the file interface
|
||||
var file = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
//point it at the file we want to get at
|
||||
file.initWithPath(filename);
|
||||
|
||||
// file is nsIFile, data is a string
|
||||
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
|
||||
.createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
var runFile = function (w) {
|
||||
var nsIFilePicker = Ci.nsIFilePicker;
|
||||
|
||||
// use 0x02 | 0x10 to open file for appending.
|
||||
foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0);
|
||||
// write, create, truncate
|
||||
// In a c file operation, we have no need to set file mode with or operation,
|
||||
// directly using "r" or "w" usually.
|
||||
|
||||
foStream.write(content, content.length);
|
||||
foStream.close();
|
||||
};
|
||||
|
||||
var saveAsFile = function(w, content){
|
||||
//define the interface
|
||||
var nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||
//define the file picker window
|
||||
fp.init(w, "Select a File", nsIFilePicker.modeSave);
|
||||
fp.appendFilter("JavaScript Files","*.js");
|
||||
//show the window
|
||||
var res = fp.show();
|
||||
//if we got a file
|
||||
if ((res == nsIFilePicker.returnOK) || (res == nsIFilePicker.returnReplace)){
|
||||
var thefile = fp.file;
|
||||
|
||||
//forcing the user to save as a .js file
|
||||
if (thefile.path.indexOf(".js") == -1){
|
||||
//define the file interface
|
||||
var file = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
//point it at the file we want to get at
|
||||
file.initWithPath(thefile.path+".js");
|
||||
var thefile = file;
|
||||
}
|
||||
|
||||
// file is nsIFile, data is a string
|
||||
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
|
||||
.createInstance(Components.interfaces.nsIFileOutputStream);
|
||||
//define the file picker window
|
||||
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||
fp.init(w, "Select a File", nsIFilePicker.modeOpen);
|
||||
fp.appendFilter("JavaScript Files","*.js");
|
||||
|
||||
// use 0x02 | 0x10 to open file for appending.
|
||||
foStream.init(thefile, 0x02 | 0x08 | 0x20, 0666, 0);
|
||||
// write, create, truncate
|
||||
// In a c file operation, we have no need to set file mode with or operation,
|
||||
// directly using "r" or "w" usually.
|
||||
foStream.write(content, content.length);
|
||||
foStream.close();
|
||||
return thefile.path;
|
||||
}
|
||||
};
|
||||
|
||||
var openFile = function(w){
|
||||
//define the interface
|
||||
var nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||
//define the file picker window
|
||||
fp.init(w, "Select a File", nsIFilePicker.modeOpen);
|
||||
fp.appendFilter("JavaScript Files","*.js");
|
||||
//show the window
|
||||
var res = fp.show();
|
||||
//if we got a file
|
||||
if (res == nsIFilePicker.returnOK){
|
||||
var thefile = fp.file;
|
||||
//create the paramObj with a files array attrib
|
||||
var data = getFile(thefile.path);
|
||||
// if we get a file
|
||||
var res = fp.show();
|
||||
if (res == nsIFilePicker.returnOK) {
|
||||
var thefile = fp.file;
|
||||
|
||||
return {path:thefile.path, data:data};
|
||||
//create the paramObj with a files array attrib
|
||||
var paramObj = {};
|
||||
paramObj.files = [];
|
||||
paramObj.files.push(thefile.path);
|
||||
}
|
||||
}
|
||||
|
||||
var saveFile = function (w, content, filename) {
|
||||
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
file.initWithPath(filename);
|
||||
|
||||
var foStream = Cc["@mozilla.org/network/file-output-stream;1"]
|
||||
.createInstance(Ci.nsIFileOutputStream);
|
||||
|
||||
// use 0x02 | 0x10 to open file for appending.
|
||||
foStream.init(file, 0x02 | 0x08 | 0x20, 0666, 0);
|
||||
// write, create, truncate
|
||||
// In a c file operation, we have no need to set file mode with or operation,
|
||||
// directly using "r" or "w" usually.
|
||||
|
||||
foStream.write(content, content.length);
|
||||
foStream.close();
|
||||
};
|
||||
|
||||
var saveAsFile = function (w, content) {
|
||||
var nsIFilePicker = Ci.nsIFilePicker;
|
||||
|
||||
// define the file picker window
|
||||
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||
fp.init(w, "Select a File", nsIFilePicker.modeSave);
|
||||
fp.appendFilter("JavaScript Files","*.js");
|
||||
|
||||
//if we get a file
|
||||
var res = fp.show();
|
||||
if ((res == nsIFilePicker.returnOK) || (res == nsIFilePicker.returnReplace)) {
|
||||
var thefile = fp.file;
|
||||
|
||||
// forcing the user to save as a .js file
|
||||
if (thefile.path.indexOf(".js") == -1){
|
||||
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
file.initWithPath(thefile.path + ".js");
|
||||
var thefile = file;
|
||||
}
|
||||
};
|
||||
|
||||
var getFile = function(path){
|
||||
//define the file interface
|
||||
var file = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
//point it at the file we want to get at
|
||||
file.initWithPath(path);
|
||||
// define file stream interfaces
|
||||
var data = "";
|
||||
var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
|
||||
.createInstance(Components.interfaces.nsIFileInputStream);
|
||||
var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
|
||||
.createInstance(Components.interfaces.nsIScriptableInputStream);
|
||||
fstream.init(file, -1, 0, 0);
|
||||
sstream.init(fstream);
|
||||
|
||||
//pull the contents of the file out
|
||||
var str = sstream.read(4096);
|
||||
while (str.length > 0) {
|
||||
data += str;
|
||||
str = sstream.read(4096);
|
||||
}
|
||||
// file is nsIFile, data is a string
|
||||
var foStream = Cc["@mozilla.org/network/file-output-stream;1"]
|
||||
.createInstance(Ci.nsIFileOutputStream);
|
||||
|
||||
sstream.close();
|
||||
fstream.close();
|
||||
// use 0x02 | 0x10 to open file for appending.
|
||||
foStream.init(thefile, 0x02 | 0x08 | 0x20, 0666, 0);
|
||||
// write, create, truncate
|
||||
// In a c file operation, we have no need to set file mode with or operation,
|
||||
// directly using "r" or "w" usually.
|
||||
foStream.write(content, content.length);
|
||||
foStream.close();
|
||||
|
||||
//data = data.replace(/\r|\n|\r\n/g, "");
|
||||
return data;
|
||||
};
|
||||
return thefile.path;
|
||||
}
|
||||
}
|
||||
|
||||
var openFile = function (w) {
|
||||
var nsIFilePicker = Ci.nsIFilePicker;
|
||||
|
||||
// define the file picker window
|
||||
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||
fp.init(w, "Select a File", nsIFilePicker.modeOpen);
|
||||
fp.appendFilter("JavaScript Files", "*.js");
|
||||
|
||||
// if we get a file
|
||||
var res = fp.show();
|
||||
if (res == nsIFilePicker.returnOK) {
|
||||
var thefile = fp.file;
|
||||
var data = getFile(thefile.path);
|
||||
|
||||
return {path: thefile.path, data: data};
|
||||
}
|
||||
}
|
||||
|
||||
var getFile = function (path) {
|
||||
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
file.initWithPath(path);
|
||||
|
||||
var data = "";
|
||||
var fstream = Cc["@mozilla.org/network/file-input-stream;1"]
|
||||
.createInstance(Ci.nsIFileInputStream);
|
||||
var sstream = Cc["@mozilla.org/scriptableinputstream;1"]
|
||||
.createInstance(Ci.nsIScriptableInputStream);
|
||||
fstream.init(file, -1, 0, 0);
|
||||
sstream.init(fstream);
|
||||
|
||||
//pull the contents of the file out
|
||||
var str = sstream.read(4096);
|
||||
while (str.length > 0) {
|
||||
data += str;
|
||||
str = sstream.read(4096);
|
||||
}
|
||||
|
||||
sstream.close();
|
||||
fstream.close();
|
||||
|
||||
//data = data.replace(/\r|\n|\r\n/g, "");
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Called to get the state of an individual preference.
|
||||
|
@ -273,8 +261,9 @@ var checkChrome = function() {
|
|||
*/
|
||||
function getPreference(aPrefName, aDefaultValue) {
|
||||
try {
|
||||
var branch = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
var branch = Cc["@mozilla.org/preferences-service;1"]
|
||||
.getService(Ci.nsIPrefBranch);
|
||||
|
||||
switch (typeof aDefaultValue) {
|
||||
case ('boolean'):
|
||||
return branch.getBoolPref(aPrefName);
|
||||
|
@ -285,7 +274,7 @@ function getPreference(aPrefName, aDefaultValue) {
|
|||
default:
|
||||
return branch.getComplexValue(aPrefName);
|
||||
}
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
return aDefaultValue;
|
||||
}
|
||||
}
|
||||
|
@ -303,8 +292,9 @@ function getPreference(aPrefName, aDefaultValue) {
|
|||
*/
|
||||
function setPreference(aName, aValue) {
|
||||
try {
|
||||
var branch = Components.classes["@mozilla.org/preferences-service;1"].
|
||||
getService(Components.interfaces.nsIPrefBranch);
|
||||
var branch = Cc["@mozilla.org/preferences-service;1"]
|
||||
.getService(Ci.nsIPrefBranch);
|
||||
|
||||
switch (typeof aValue) {
|
||||
case ('boolean'):
|
||||
branch.setBoolPref(aName, aValue);
|
||||
|
@ -318,7 +308,7 @@ function setPreference(aName, aValue) {
|
|||
default:
|
||||
branch.setComplexValue(aName, aValue);
|
||||
}
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -332,14 +322,12 @@ function setPreference(aName, aValue) {
|
|||
* Sleeps the given number of milliseconds
|
||||
*/
|
||||
function sleep(milliseconds) {
|
||||
// We basically just call this once after the specified number of milliseconds
|
||||
var timeup = false;
|
||||
function wait() { timeup = true; }
|
||||
hwindow.setTimeout(wait, milliseconds);
|
||||
|
||||
var thread = Components.classes["@mozilla.org/thread-manager;1"].
|
||||
getService().currentThread;
|
||||
while(!timeup) {
|
||||
hwindow.setTimeout(function () { timeup = true; }, milliseconds);
|
||||
var thread = Cc["@mozilla.org/thread-manager;1"]
|
||||
.getService().currentThread;
|
||||
while (!timeup) {
|
||||
thread.processNextEvent(true);
|
||||
}
|
||||
}
|
||||
|
@ -356,7 +344,7 @@ function assert(callback, message, thisObject) {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unwraps a node which is wrapped into a XPCNativeWrapper or XrayWrapper
|
||||
*
|
||||
|
@ -374,6 +362,7 @@ function unwrapNode(aNode) {
|
|||
node = node.wrappedJSObject;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -384,13 +373,14 @@ function unwrapNode(aNode) {
|
|||
*/
|
||||
function TimeoutError(message, fileName, lineNumber) {
|
||||
var err = new Error();
|
||||
this.message = (message === undefined ? err.message : message);
|
||||
this.fileName = (fileName === undefined ? err.fileName : fileName);
|
||||
this.lineNumber = (lineNumber === undefined ? err.lineNumber : lineNumber);
|
||||
|
||||
if (err.stack) {
|
||||
this.stack = err.stack;
|
||||
}
|
||||
this.message = message === undefined ? err.message : message;
|
||||
this.fileName = fileName === undefined ? err.fileName : fileName;
|
||||
this.lineNumber = lineNumber === undefined ? err.lineNumber : lineNumber;
|
||||
};
|
||||
}
|
||||
TimeoutError.prototype = new Error();
|
||||
TimeoutError.prototype.constructor = TimeoutError;
|
||||
TimeoutError.prototype.name = 'TimeoutError';
|
||||
|
@ -402,7 +392,8 @@ function waitFor(callback, message, timeout, interval, thisObject) {
|
|||
timeout = timeout || 5000;
|
||||
interval = interval || 100;
|
||||
|
||||
var self = {counter: 0, result: callback.call(thisObject)};
|
||||
var self = {counter: 0,
|
||||
result: callback.call(thisObject)};
|
||||
|
||||
function wait() {
|
||||
self.counter += interval;
|
||||
|
@ -410,10 +401,10 @@ function waitFor(callback, message, timeout, interval, thisObject) {
|
|||
}
|
||||
|
||||
var timeoutInterval = hwindow.setInterval(wait, interval);
|
||||
var thread = Components.classes["@mozilla.org/thread-manager;1"].
|
||||
getService().currentThread;
|
||||
var thread = Cc["@mozilla.org/thread-manager;1"]
|
||||
.getService().currentThread;
|
||||
|
||||
while((self.result != true) && (self.counter < timeout)) {
|
||||
while ((self.result != true) && (self.counter < timeout)) {
|
||||
thread.processNextEvent(true);
|
||||
}
|
||||
|
||||
|
@ -437,6 +428,7 @@ function getChromeOffset(elem) {
|
|||
var win = elem.ownerDocument.defaultView;
|
||||
// Calculate x offset
|
||||
var chromeWidth = 0;
|
||||
|
||||
if (win["name"] != "sidebar") {
|
||||
chromeWidth = win.outerWidth - win.innerWidth;
|
||||
}
|
||||
|
@ -447,9 +439,10 @@ function getChromeOffset(elem) {
|
|||
if (chromeHeight > 0) {
|
||||
// window.innerHeight doesn't include the addon or find bar, so account for these if present
|
||||
var addonbar = win.document.getElementById("addon-bar");
|
||||
if (addonbar) {
|
||||
if (addonbar) {
|
||||
chromeHeight -= addonbar.scrollHeight;
|
||||
}
|
||||
|
||||
var findbar = win.document.getElementById("FindToolbar");
|
||||
if (findbar) {
|
||||
chromeHeight -= findbar.scrollHeight;
|
||||
|
@ -466,7 +459,8 @@ function takeScreenshot(node, name, highlights) {
|
|||
var rect, win, width, height, left, top, needsOffset;
|
||||
// node can be either a window or an arbitrary DOM node
|
||||
try {
|
||||
win = node.ownerDocument.defaultView; // node is an arbitrary DOM node
|
||||
// node is an arbitrary DOM node
|
||||
win = node.ownerDocument.defaultView;
|
||||
rect = node.getBoundingClientRect();
|
||||
width = rect.width;
|
||||
height = rect.height;
|
||||
|
@ -475,7 +469,8 @@ function takeScreenshot(node, name, highlights) {
|
|||
// offset for highlights not needed as they will be relative to this node
|
||||
needsOffset = false;
|
||||
} catch (e) {
|
||||
win = node; // node is a window
|
||||
// node is a window
|
||||
win = node;
|
||||
width = win.innerWidth;
|
||||
height = win.innerHeight;
|
||||
top = 0;
|
||||
|
@ -491,7 +486,7 @@ function takeScreenshot(node, name, highlights) {
|
|||
var ctx = canvas.getContext("2d");
|
||||
// Draws the DOM contents of the window to the canvas
|
||||
ctx.drawWindow(win, left, top, width, height, "rgb(255,255,255)");
|
||||
|
||||
|
||||
// This section is for drawing a red rectangle around each element passed in via the highlights array
|
||||
if (highlights) {
|
||||
ctx.lineWidth = "2";
|
||||
|
@ -516,13 +511,11 @@ function takeScreenshot(node, name, highlights) {
|
|||
// Draw the rectangle
|
||||
ctx.strokeRect(rect.left + offsetX, rect.top + offsetY, rect.width, rect.height);
|
||||
}
|
||||
} // end highlights
|
||||
}
|
||||
|
||||
// if there is a name save the file, else return dataURL
|
||||
if (name) {
|
||||
return saveCanvas(canvas, name);
|
||||
}
|
||||
return canvas.toDataURL("image/png","");
|
||||
return (name ? saveCanvas(canvas, name)
|
||||
: canvas.toDataURL("image/png",""));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -530,26 +523,24 @@ function takeScreenshot(node, name, highlights) {
|
|||
* Returns the filepath of the saved file
|
||||
*/
|
||||
function saveCanvas(canvas, name) {
|
||||
var file = Components.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties)
|
||||
.get("TmpD", Components.interfaces.nsIFile);
|
||||
var file = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
|
||||
file.append("mozmill_screens");
|
||||
file.append(name + ".png");
|
||||
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
|
||||
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
|
||||
|
||||
// create a data url from the canvas and then create URIs of the source and targets
|
||||
var io = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
// create a data url from the canvas and then create URIs of the source and targets
|
||||
var io = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
var source = io.newURI(canvas.toDataURL("image/png", ""), "UTF8", null);
|
||||
var target = io.newFileURI(file)
|
||||
|
||||
// prepare to save the canvas data
|
||||
var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
|
||||
.createInstance(Components.interfaces.nsIWebBrowserPersist);
|
||||
var target = io.newFileURI(file);
|
||||
|
||||
// prepare to save the canvas data
|
||||
var persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
|
||||
.createInstance(Ci.nsIWebBrowserPersist);
|
||||
|
||||
persist.persistFlags = Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
|
||||
persist.persistFlags |= Ci.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
|
||||
|
||||
persist.persistFlags = Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
|
||||
persist.persistFlags |= Components.interfaces.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
|
||||
|
||||
// save the canvas data to the file
|
||||
persist.saveURI(source, null, null, null, null, file);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ try:
|
|||
except IOError:
|
||||
description = ''
|
||||
|
||||
version = "0.1"
|
||||
version = "1.0"
|
||||
|
||||
dependencies = ['ManifestDestiny',
|
||||
'mozhttpd',
|
||||
|
|
Загрузка…
Ссылка в новой задаче