Browse files

Merge remote-tracking branch 'upstream/master' into bug/no-Iterator@7…

…43386

Conflicts:
	packages/addon-kit/tests/test-widget.js
  • Loading branch information...
2 parents fbd23f5 + ac13471 commit 997d9019a41c98157b152a4173f152078023006b @Gozala Gozala committed Apr 10, 2012
View
4 doc/dev-guide-source/tutorials/adding-menus.md
@@ -17,6 +17,10 @@ modules for add-on developers to use. Luckily, Erik Vold has written
a [`menuitems`](https://github.com/erikvold/menuitems-jplib) package
that enables us to add menu items.
+This tutorial does double-duty. It describes the general method for
+using an external, third-party package in your add-on, and it
+describes how to add a menu item using the `menuitems` package in particular.
+
## Installing `menuitems` ##
First we'll download `menuitems` from
View
80 packages/addon-kit/tests/test-widget.js
@@ -28,17 +28,17 @@ exports.testConstructor = function(test) {
let w = widgets.Widget({ id: "fooID", label: "foo", content: "bar" });
AddonsMgrListener.onInstalled();
test.assertEqual(widgetCount(), widgetStartCount + 1, "panel has correct number of child elements after widget construction");
-
+
// test widget height
test.assertEqual(widgetNode(0).firstChild.boxObject.height, 16, "widget has correct default height");
-
+
AddonsMgrListener.onUninstalling();
w.destroy();
AddonsMgrListener.onUninstalled();
w.destroy();
test.pass("Multiple destroys do not cause an error");
test.assertEqual(widgetCount(), widgetStartCount, "panel has correct number of child elements after destroy");
-
+
// Test automatic widget destroy on unload
let loader = Loader(module);
let widgetsFromLoader = loader.require("widget");
@@ -47,13 +47,13 @@ exports.testConstructor = function(test) {
test.assertEqual(widgetCount(), widgetStartCount + 1, "widget has been correctly added");
loader.unload();
test.assertEqual(widgetCount(), widgetStartCount, "widget has been destroyed on module unload");
-
+
// Test nothing
test.assertRaises(
function() widgets.Widget({}),
"The widget must have a non-empty label property.",
"throws on no properties");
-
+
// Test no label
test.assertRaises(
function() widgets.Widget({content: "foo"}),
@@ -65,13 +65,13 @@ exports.testConstructor = function(test) {
function() widgets.Widget({label: "", content: "foo"}),
"The widget must have a non-empty label property.",
"throws on empty label");
-
+
// Test no content or image
test.assertRaises(
function() widgets.Widget({id: "fooID", label: "foo"}),
"No content or contentURL property found. Widgets must have one or the other.",
"throws on no content");
-
+
// Test empty content, no image
test.assertRaises(
function() widgets.Widget({id:"fooID", label: "foo", content: ""}),
@@ -109,7 +109,7 @@ exports.testConstructor = function(test) {
let w2 = widgets.Widget({id: "id2", label: "foo", content: "bar"});
w1.destroy();
w2.destroy();
-
+
// Test position restore on create/destroy/create
// Create 3 ordered widgets
let w1 = widgets.Widget({id: "first", label:"first", content: "bar"});
@@ -127,7 +127,7 @@ exports.testConstructor = function(test) {
w2.destroy();
w3.destroy();
AddonsMgrListener.onUninstalled();
-
+
// Test concurrent widget module instances on addon-bar hiding
let loader = Loader(module);
let anotherWidgetsInstance = loader.require("widget");
@@ -151,15 +151,15 @@ exports.testConstructor = function(test) {
test.assert(!container().collapsed, "UI is still visible when we have removed all widget but still not called onUninstalled");
AddonsMgrListener.onUninstalled();
test.assert(container().collapsed, "UI is hidden when we have removed all widget and called onUninstalled");
-
+
// Helper for testing a single widget.
// Confirms proper addition and content setup.
function testSingleWidget(widgetOptions) {
// We have to display which test is being run, because here we do not
// use the regular test framework but rather a custom one that iterates
// the `tests` array.
console.info("executing: " + widgetOptions.id);
-
+
let startCount = widgetCount();
let widget = widgets.Widget(widgetOptions);
let node = widgetNode(startCount);
@@ -219,7 +219,7 @@ exports.testConstructor = function(test) {
label: "image url widget",
contentURL: require("self").data.url("test.html"),
contentScript: "self.postMessage({title: document.title, " +
- "tag: document.body.firstElementChild.tagName, " +
+ "tag: document.body.firstElementChild.tagName, " +
"content: document.body.firstElementChild.innerHTML});",
contentScriptWhen: "end",
onMessage: function (message) {
@@ -237,7 +237,7 @@ exports.testConstructor = function(test) {
label: "web uri widget",
contentURL: require("self").data.url("test.html"),
contentScript: "self.postMessage({title: document.title, " +
- "tag: document.body.firstElementChild.tagName, " +
+ "tag: document.body.firstElementChild.tagName, " +
"content: document.body.firstElementChild.innerHTML});",
contentScriptWhen: "end",
onMessage: function (message) {
@@ -380,7 +380,7 @@ exports.testConstructor = function(test) {
// test updating widget contentURL
let url1 = "data:text/html,<body>foodle</body>";
let url2 = "data:text/html,<body>nistel</body>";
-
+
tests.push(function testUpdatingContentURL() testSingleWidget({
id: "content",
label: "content update test widget",
@@ -516,23 +516,23 @@ exports.testConstructor = function(test) {
});
}});
});
-
+
// test window closing
tests.push(function testWindowClosing() {
// 1/ Create a new widget
let w1Opts = {
- id:"first",
- label: "first widget",
+ id:"first",
+ label: "first widget",
content: "first content",
contentScript: "self.port.on('event', function () self.port.emit('event'))"
};
let widget = testSingleWidget(w1Opts);
let windows = require("windows").browserWindows;
-
+
// 2/ Retrieve a WidgetView for the initial browser window
let acceptDetach = false;
let mainView = widget.getView(windows.activeWindow);
- test.assert(mainView, "Got first widget view");
+ test.assert(mainView, "Got first widget view");
mainView.on("detach", function () {
// 8/ End of our test. Accept detach event only when it occurs after
// widget.destroy()
@@ -546,7 +546,7 @@ exports.testConstructor = function(test) {
acceptDetach = true;
widget.destroy();
});
-
+
// 3/ First: open a new browser window
windows.open({
url: "about:blank",
@@ -567,37 +567,37 @@ exports.testConstructor = function(test) {
"emit on a destroyed view should throw");
widget.port.emit("event");
});
-
+
// 5/ Destroy this window
- window.close();
+ window.close();
}
});
});
-
+
tests.push(function testAddonBarHide() {
// Hide the addon-bar
browserWindow.setToolbarVisibility(container(), false);
-
+
// Then open a browser window and verify that the addon-bar remains hidden
tabBrowser.addTab("about:blank", { inNewWindow: true, onLoad: function(e) {
let browserWindow = e.target.defaultView;
let doc = browserWindow.document;
function container2() doc.getElementById("addon-bar");
function widgetCount2() container2() ? container2().childNodes.length : 0;
let widgetStartCount2 = widgetCount2();
-
+
let w1Opts = {id:"first", label: "first widget", content: "first content"};
let w1 = testSingleWidget(w1Opts);
test.assertEqual(widgetCount2(), widgetStartCount2 + 1, "2nd window has correct number of child elements after widget creation");
w1.destroy();
test.assertEqual(widgetCount2(), widgetStartCount2, "2nd window has correct number of child elements after widget destroy");
-
+
test.assert(container().collapsed, "1st window has an hidden addon-bar");
test.assert(container2().collapsed, "2nd window has an hidden addon-bar");
-
+
browserWindow.setToolbarVisibility(container(), true);
-
+
closeBrowserWindow(browserWindow, function() {
doneTest();
});
@@ -767,7 +767,7 @@ exports.testWidgetViews = function testWidgetViews(test) {
});
}
});
-
+
};
exports.testWidgetViewsUIEvents = function testWidgetViewsUIEvents(test) {
@@ -787,10 +787,10 @@ exports.testWidgetViewsUIEvents = function testWidgetViewsUIEvents(test) {
test.pass("Got attach event");
},
onClick: function (eventView) {
- test.assertEqual(view, eventView,
+ test.assertEqual(view, eventView,
"event first argument is equal to the WidgetView");
let view2 = widget.getView(require("windows").browserWindows.activeWindow);
- test.assertEqual(view, view2,
+ test.assertEqual(view, view2,
"widget.getView return the same WidgetView");
widget.destroy();
test.done();
@@ -809,13 +809,13 @@ exports.testWidgetViewsCustomEvents = function testWidgetViewsCustomEvents(test)
contentScriptWhen: "ready",
onAttach: function(view) {
view.port.on("event", function (data) {
- test.assertEqual(data, "ok",
+ test.assertEqual(data, "ok",
"event argument is valid on WidgetView");
});
},
});
widget.port.on("event", function (data) {
- test.assertEqual(data, "ok",
+ test.assertEqual(data, "ok",
"event argument is valid on Widget");
widget.destroy();
test.done();
@@ -825,35 +825,35 @@ exports.testWidgetViewsCustomEvents = function testWidgetViewsCustomEvents(test)
exports.testWidgetViewsTooltip = function testWidgetViewsTooltip(test) {
test.waitUntilDone();
const widgets = require("widget");
-
+
let widget = new widgets.Widget({
id: "foo",
label: "foo",
content: "foo"
});
let view = widget.getView(require("windows").browserWindows.activeWindow);
widget.tooltip = null;
- test.assertEqual(view.tooltip, "foo",
+ test.assertEqual(view.tooltip, "foo",
"view tooltip defaults to base widget label");
- test.assertEqual(widget.tooltip, "foo",
+ test.assertEqual(widget.tooltip, "foo",
"tooltip defaults to base widget label");
widget.destroy();
test.done();
};
exports.testWidgetMove = function testWidgetMove(test) {
test.waitUntilDone();
-
+
let windowUtils = require("window-utils");
let widgets = require("widget");
-
+
let browserWindow = windowUtils.activeBrowserWindow;
let doc = browserWindow.document;
-
+
let label = "unique-widget-label";
let origMessage = "message after node move";
let gotFirstReady = false;
-
+
let widget = widgets.Widget({
id: "foo",
label: label,
View
94 packages/api-utils/lib/timer.js
@@ -2,77 +2,49 @@
* 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/. */
-"use strict";
+'use strict';
-const { CC } = require("chrome");
-const { Unknown } = require("./xpcom");
-const { when: unload } = require("./unload");
+const { CC, Ci } = require('chrome');
+const { when: unload } = require('./unload');
+const { TYPE_ONE_SHOT, TYPE_REPEATING_SLACK } = Ci.nsITimer;
const Timer = CC('@mozilla.org/timer;1', 'nsITimer');
-
-// Registry for all timers.
-const timers = (function(map, id) {
- return Object.defineProperties(function registry(key, fallback) {
- return key in map ? map[key] : fallback;
- }, {
- register: { value: function(value) (map[++id] = value, id) },
- unregister: { value: function(key) delete map[key] },
- forEach: { value: function(callback) Object.keys(map).forEach(callback) }
- });
-})(Object.create(null), 0);
-
-const TimerCallback = Unknown.extend({
- interfaces: [ 'nsITimerCallback' ],
- initialize: function initialize(id, callback, rest) {
- this.id = id;
- this.callback = callback;
- this.arguments = rest;
- }
-});
-
-const TimeoutCallback = TimerCallback.extend({
- type: 0, // nsITimer.TYPE_ONE_SHOT
- notify: function notify() {
- try {
- timers.unregister(this.id);
- this.callback.apply(null, this.arguments);
- }
- catch (error) {
- console.exception(error);
+const timers = Object.create(null);
+
+// Last timer id.
+let lastID = 0;
+
+// Sets typer either by timeout or by interval
+// depending on a given type.
+function setTimer(type, callback, delay) {
+ let id = ++ lastID;
+ let timer = timers[id] = Timer();
+ let args = Array.slice(arguments, 3);
+ timer.initWithCallback({
+ notify: function notify() {
+ try {
+ if (type === TYPE_ONE_SHOT)
+ delete timers[id];
+ callback.apply(null, args);
+ }
+ catch(error) {
+ console.exception(error);
+ }
}
- }
-});
-
-const IntervalCallback = TimerCallback.extend({
- type: 1, // nsITimer.TYPE_REPEATING_SLACK
- notify: function notify() {
- try {
- this.callback.apply(null, this.arguments);
- }
- catch (error) {
- console.exception(error);
- }
- }
-});
-
-function setTimer(TimerCallback, listener, delay) {
- let timer = Timer();
- let id = timers.register(timer);
- let callback = TimerCallback.new(id, listener, Array.slice(arguments, 3));
- timer.initWithCallback(callback, delay || 0, TimerCallback.type);
+ }, delay || 0, type);
return id;
}
function unsetTimer(id) {
- let timer = timers(id);
- timers.unregister(id);
+ let timer = timers[id];
+ delete timers[id];
if (timer)
timer.cancel();
}
-exports.setTimeout = setTimer.bind(null, TimeoutCallback);
-exports.setInterval = setTimer.bind(null, IntervalCallback);
-exports.clearTimeout = unsetTimer;
-exports.clearInterval = unsetTimer;
+exports.setTimeout = setTimer.bind(null, TYPE_ONE_SHOT);
+exports.setInterval = setTimer.bind(null, TYPE_REPEATING_SLACK);
+exports.clearTimeout = unsetTimer.bind(null);
+exports.clearInterval = unsetTimer.bind(null);
-unload(function() { timers.forEach(unsetTimer); });
+unload(function() { Object.keys(timers).forEach(unsetTimer) });

0 comments on commit 997d901

Please sign in to comment.