Bug 753099 Update peptest to work with global compartments change r=ctalbert

This commit is contained in:
Mark Cote 2012-05-09 13:59:31 -07:00
parent 875848ef77
commit 1b776c5ada
13 changed files with 1206 additions and 1173 deletions

View File

@ -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);
};

View File

@ -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;
};

View File

@ -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();

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -11,7 +11,7 @@ try:
except IOError:
description = ''
version = "0.1"
version = "1.0"
dependencies = ['ManifestDestiny',
'mozhttpd',