Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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

…43386

Conflicts:
	packages/addon-kit/tests/test-widget.js
  • Loading branch information...
commit 997d9019a41c98157b152a4173f152078023006b 2 parents fbd23f5 + ac13471
Irakli Gozalishvili Gozala authored
4 doc/dev-guide-source/tutorials/adding-menus.md
Source Rendered
@@ -17,6 +17,10 @@ modules for add-on developers to use. Luckily, Erik Vold has written
17 17 a [`menuitems`](https://github.com/erikvold/menuitems-jplib) package
18 18 that enables us to add menu items.
19 19
  20 +This tutorial does double-duty. It describes the general method for
  21 +using an external, third-party package in your add-on, and it
  22 +describes how to add a menu item using the `menuitems` package in particular.
  23 +
20 24 ## Installing `menuitems` ##
21 25
22 26 First we'll download `menuitems` from
80 packages/addon-kit/tests/test-widget.js
@@ -28,17 +28,17 @@ exports.testConstructor = function(test) {
28 28 let w = widgets.Widget({ id: "fooID", label: "foo", content: "bar" });
29 29 AddonsMgrListener.onInstalled();
30 30 test.assertEqual(widgetCount(), widgetStartCount + 1, "panel has correct number of child elements after widget construction");
31   -
  31 +
32 32 // test widget height
33 33 test.assertEqual(widgetNode(0).firstChild.boxObject.height, 16, "widget has correct default height");
34   -
  34 +
35 35 AddonsMgrListener.onUninstalling();
36 36 w.destroy();
37 37 AddonsMgrListener.onUninstalled();
38 38 w.destroy();
39 39 test.pass("Multiple destroys do not cause an error");
40 40 test.assertEqual(widgetCount(), widgetStartCount, "panel has correct number of child elements after destroy");
41   -
  41 +
42 42 // Test automatic widget destroy on unload
43 43 let loader = Loader(module);
44 44 let widgetsFromLoader = loader.require("widget");
@@ -47,13 +47,13 @@ exports.testConstructor = function(test) {
47 47 test.assertEqual(widgetCount(), widgetStartCount + 1, "widget has been correctly added");
48 48 loader.unload();
49 49 test.assertEqual(widgetCount(), widgetStartCount, "widget has been destroyed on module unload");
50   -
  50 +
51 51 // Test nothing
52 52 test.assertRaises(
53 53 function() widgets.Widget({}),
54 54 "The widget must have a non-empty label property.",
55 55 "throws on no properties");
56   -
  56 +
57 57 // Test no label
58 58 test.assertRaises(
59 59 function() widgets.Widget({content: "foo"}),
@@ -65,13 +65,13 @@ exports.testConstructor = function(test) {
65 65 function() widgets.Widget({label: "", content: "foo"}),
66 66 "The widget must have a non-empty label property.",
67 67 "throws on empty label");
68   -
  68 +
69 69 // Test no content or image
70 70 test.assertRaises(
71 71 function() widgets.Widget({id: "fooID", label: "foo"}),
72 72 "No content or contentURL property found. Widgets must have one or the other.",
73 73 "throws on no content");
74   -
  74 +
75 75 // Test empty content, no image
76 76 test.assertRaises(
77 77 function() widgets.Widget({id:"fooID", label: "foo", content: ""}),
@@ -109,7 +109,7 @@ exports.testConstructor = function(test) {
109 109 let w2 = widgets.Widget({id: "id2", label: "foo", content: "bar"});
110 110 w1.destroy();
111 111 w2.destroy();
112   -
  112 +
113 113 // Test position restore on create/destroy/create
114 114 // Create 3 ordered widgets
115 115 let w1 = widgets.Widget({id: "first", label:"first", content: "bar"});
@@ -127,7 +127,7 @@ exports.testConstructor = function(test) {
127 127 w2.destroy();
128 128 w3.destroy();
129 129 AddonsMgrListener.onUninstalled();
130   -
  130 +
131 131 // Test concurrent widget module instances on addon-bar hiding
132 132 let loader = Loader(module);
133 133 let anotherWidgetsInstance = loader.require("widget");
@@ -151,7 +151,7 @@ exports.testConstructor = function(test) {
151 151 test.assert(!container().collapsed, "UI is still visible when we have removed all widget but still not called onUninstalled");
152 152 AddonsMgrListener.onUninstalled();
153 153 test.assert(container().collapsed, "UI is hidden when we have removed all widget and called onUninstalled");
154   -
  154 +
155 155 // Helper for testing a single widget.
156 156 // Confirms proper addition and content setup.
157 157 function testSingleWidget(widgetOptions) {
@@ -159,7 +159,7 @@ exports.testConstructor = function(test) {
159 159 // use the regular test framework but rather a custom one that iterates
160 160 // the `tests` array.
161 161 console.info("executing: " + widgetOptions.id);
162   -
  162 +
163 163 let startCount = widgetCount();
164 164 let widget = widgets.Widget(widgetOptions);
165 165 let node = widgetNode(startCount);
@@ -219,7 +219,7 @@ exports.testConstructor = function(test) {
219 219 label: "image url widget",
220 220 contentURL: require("self").data.url("test.html"),
221 221 contentScript: "self.postMessage({title: document.title, " +
222   - "tag: document.body.firstElementChild.tagName, " +
  222 + "tag: document.body.firstElementChild.tagName, " +
223 223 "content: document.body.firstElementChild.innerHTML});",
224 224 contentScriptWhen: "end",
225 225 onMessage: function (message) {
@@ -237,7 +237,7 @@ exports.testConstructor = function(test) {
237 237 label: "web uri widget",
238 238 contentURL: require("self").data.url("test.html"),
239 239 contentScript: "self.postMessage({title: document.title, " +
240   - "tag: document.body.firstElementChild.tagName, " +
  240 + "tag: document.body.firstElementChild.tagName, " +
241 241 "content: document.body.firstElementChild.innerHTML});",
242 242 contentScriptWhen: "end",
243 243 onMessage: function (message) {
@@ -380,7 +380,7 @@ exports.testConstructor = function(test) {
380 380 // test updating widget contentURL
381 381 let url1 = "data:text/html,<body>foodle</body>";
382 382 let url2 = "data:text/html,<body>nistel</body>";
383   -
  383 +
384 384 tests.push(function testUpdatingContentURL() testSingleWidget({
385 385 id: "content",
386 386 label: "content update test widget",
@@ -516,23 +516,23 @@ exports.testConstructor = function(test) {
516 516 });
517 517 }});
518 518 });
519   -
  519 +
520 520 // test window closing
521 521 tests.push(function testWindowClosing() {
522 522 // 1/ Create a new widget
523 523 let w1Opts = {
524   - id:"first",
525   - label: "first widget",
  524 + id:"first",
  525 + label: "first widget",
526 526 content: "first content",
527 527 contentScript: "self.port.on('event', function () self.port.emit('event'))"
528 528 };
529 529 let widget = testSingleWidget(w1Opts);
530 530 let windows = require("windows").browserWindows;
531   -
  531 +
532 532 // 2/ Retrieve a WidgetView for the initial browser window
533 533 let acceptDetach = false;
534 534 let mainView = widget.getView(windows.activeWindow);
535   - test.assert(mainView, "Got first widget view");
  535 + test.assert(mainView, "Got first widget view");
536 536 mainView.on("detach", function () {
537 537 // 8/ End of our test. Accept detach event only when it occurs after
538 538 // widget.destroy()
@@ -546,7 +546,7 @@ exports.testConstructor = function(test) {
546 546 acceptDetach = true;
547 547 widget.destroy();
548 548 });
549   -
  549 +
550 550 // 3/ First: open a new browser window
551 551 windows.open({
552 552 url: "about:blank",
@@ -567,17 +567,17 @@ exports.testConstructor = function(test) {
567 567 "emit on a destroyed view should throw");
568 568 widget.port.emit("event");
569 569 });
570   -
  570 +
571 571 // 5/ Destroy this window
572   - window.close();
  572 + window.close();
573 573 }
574 574 });
575 575 });
576   -
  576 +
577 577 tests.push(function testAddonBarHide() {
578 578 // Hide the addon-bar
579 579 browserWindow.setToolbarVisibility(container(), false);
580   -
  580 +
581 581 // Then open a browser window and verify that the addon-bar remains hidden
582 582 tabBrowser.addTab("about:blank", { inNewWindow: true, onLoad: function(e) {
583 583 let browserWindow = e.target.defaultView;
@@ -585,19 +585,19 @@ exports.testConstructor = function(test) {
585 585 function container2() doc.getElementById("addon-bar");
586 586 function widgetCount2() container2() ? container2().childNodes.length : 0;
587 587 let widgetStartCount2 = widgetCount2();
588   -
  588 +
589 589 let w1Opts = {id:"first", label: "first widget", content: "first content"};
590 590 let w1 = testSingleWidget(w1Opts);
591 591 test.assertEqual(widgetCount2(), widgetStartCount2 + 1, "2nd window has correct number of child elements after widget creation");
592 592
593 593 w1.destroy();
594 594 test.assertEqual(widgetCount2(), widgetStartCount2, "2nd window has correct number of child elements after widget destroy");
595   -
  595 +
596 596 test.assert(container().collapsed, "1st window has an hidden addon-bar");
597 597 test.assert(container2().collapsed, "2nd window has an hidden addon-bar");
598   -
  598 +
599 599 browserWindow.setToolbarVisibility(container(), true);
600   -
  600 +
601 601 closeBrowserWindow(browserWindow, function() {
602 602 doneTest();
603 603 });
@@ -767,7 +767,7 @@ exports.testWidgetViews = function testWidgetViews(test) {
767 767 });
768 768 }
769 769 });
770   -
  770 +
771 771 };
772 772
773 773 exports.testWidgetViewsUIEvents = function testWidgetViewsUIEvents(test) {
@@ -787,10 +787,10 @@ exports.testWidgetViewsUIEvents = function testWidgetViewsUIEvents(test) {
787 787 test.pass("Got attach event");
788 788 },
789 789 onClick: function (eventView) {
790   - test.assertEqual(view, eventView,
  790 + test.assertEqual(view, eventView,
791 791 "event first argument is equal to the WidgetView");
792 792 let view2 = widget.getView(require("windows").browserWindows.activeWindow);
793   - test.assertEqual(view, view2,
  793 + test.assertEqual(view, view2,
794 794 "widget.getView return the same WidgetView");
795 795 widget.destroy();
796 796 test.done();
@@ -809,13 +809,13 @@ exports.testWidgetViewsCustomEvents = function testWidgetViewsCustomEvents(test)
809 809 contentScriptWhen: "ready",
810 810 onAttach: function(view) {
811 811 view.port.on("event", function (data) {
812   - test.assertEqual(data, "ok",
  812 + test.assertEqual(data, "ok",
813 813 "event argument is valid on WidgetView");
814 814 });
815 815 },
816 816 });
817 817 widget.port.on("event", function (data) {
818   - test.assertEqual(data, "ok",
  818 + test.assertEqual(data, "ok",
819 819 "event argument is valid on Widget");
820 820 widget.destroy();
821 821 test.done();
@@ -825,7 +825,7 @@ exports.testWidgetViewsCustomEvents = function testWidgetViewsCustomEvents(test)
825 825 exports.testWidgetViewsTooltip = function testWidgetViewsTooltip(test) {
826 826 test.waitUntilDone();
827 827 const widgets = require("widget");
828   -
  828 +
829 829 let widget = new widgets.Widget({
830 830 id: "foo",
831 831 label: "foo",
@@ -833,9 +833,9 @@ exports.testWidgetViewsTooltip = function testWidgetViewsTooltip(test) {
833 833 });
834 834 let view = widget.getView(require("windows").browserWindows.activeWindow);
835 835 widget.tooltip = null;
836   - test.assertEqual(view.tooltip, "foo",
  836 + test.assertEqual(view.tooltip, "foo",
837 837 "view tooltip defaults to base widget label");
838   - test.assertEqual(widget.tooltip, "foo",
  838 + test.assertEqual(widget.tooltip, "foo",
839 839 "tooltip defaults to base widget label");
840 840 widget.destroy();
841 841 test.done();
@@ -843,17 +843,17 @@ exports.testWidgetViewsTooltip = function testWidgetViewsTooltip(test) {
843 843
844 844 exports.testWidgetMove = function testWidgetMove(test) {
845 845 test.waitUntilDone();
846   -
  846 +
847 847 let windowUtils = require("window-utils");
848 848 let widgets = require("widget");
849   -
  849 +
850 850 let browserWindow = windowUtils.activeBrowserWindow;
851 851 let doc = browserWindow.document;
852   -
  852 +
853 853 let label = "unique-widget-label";
854 854 let origMessage = "message after node move";
855 855 let gotFirstReady = false;
856   -
  856 +
857 857 let widget = widgets.Widget({
858 858 id: "foo",
859 859 label: label,
94 packages/api-utils/lib/timer.js
@@ -2,77 +2,49 @@
2 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 4
5   -"use strict";
  5 +'use strict';
6 6
7   -const { CC } = require("chrome");
8   -const { Unknown } = require("./xpcom");
9   -const { when: unload } = require("./unload");
  7 +const { CC, Ci } = require('chrome');
  8 +const { when: unload } = require('./unload');
10 9
  10 +const { TYPE_ONE_SHOT, TYPE_REPEATING_SLACK } = Ci.nsITimer;
11 11 const Timer = CC('@mozilla.org/timer;1', 'nsITimer');
12   -
13   -// Registry for all timers.
14   -const timers = (function(map, id) {
15   - return Object.defineProperties(function registry(key, fallback) {
16   - return key in map ? map[key] : fallback;
17   - }, {
18   - register: { value: function(value) (map[++id] = value, id) },
19   - unregister: { value: function(key) delete map[key] },
20   - forEach: { value: function(callback) Object.keys(map).forEach(callback) }
21   - });
22   -})(Object.create(null), 0);
23   -
24   -const TimerCallback = Unknown.extend({
25   - interfaces: [ 'nsITimerCallback' ],
26   - initialize: function initialize(id, callback, rest) {
27   - this.id = id;
28   - this.callback = callback;
29   - this.arguments = rest;
30   - }
31   -});
32   -
33   -const TimeoutCallback = TimerCallback.extend({
34   - type: 0, // nsITimer.TYPE_ONE_SHOT
35   - notify: function notify() {
36   - try {
37   - timers.unregister(this.id);
38   - this.callback.apply(null, this.arguments);
39   - }
40   - catch (error) {
41   - console.exception(error);
  12 +const timers = Object.create(null);
  13 +
  14 +// Last timer id.
  15 +let lastID = 0;
  16 +
  17 +// Sets typer either by timeout or by interval
  18 +// depending on a given type.
  19 +function setTimer(type, callback, delay) {
  20 + let id = ++ lastID;
  21 + let timer = timers[id] = Timer();
  22 + let args = Array.slice(arguments, 3);
  23 + timer.initWithCallback({
  24 + notify: function notify() {
  25 + try {
  26 + if (type === TYPE_ONE_SHOT)
  27 + delete timers[id];
  28 + callback.apply(null, args);
  29 + }
  30 + catch(error) {
  31 + console.exception(error);
  32 + }
42 33 }
43   - }
44   -});
45   -
46   -const IntervalCallback = TimerCallback.extend({
47   - type: 1, // nsITimer.TYPE_REPEATING_SLACK
48   - notify: function notify() {
49   - try {
50   - this.callback.apply(null, this.arguments);
51   - }
52   - catch (error) {
53   - console.exception(error);
54   - }
55   - }
56   -});
57   -
58   -function setTimer(TimerCallback, listener, delay) {
59   - let timer = Timer();
60   - let id = timers.register(timer);
61   - let callback = TimerCallback.new(id, listener, Array.slice(arguments, 3));
62   - timer.initWithCallback(callback, delay || 0, TimerCallback.type);
  34 + }, delay || 0, type);
63 35 return id;
64 36 }
65 37
66 38 function unsetTimer(id) {
67   - let timer = timers(id);
68   - timers.unregister(id);
  39 + let timer = timers[id];
  40 + delete timers[id];
69 41 if (timer)
70 42 timer.cancel();
71 43 }
72 44
73   -exports.setTimeout = setTimer.bind(null, TimeoutCallback);
74   -exports.setInterval = setTimer.bind(null, IntervalCallback);
75   -exports.clearTimeout = unsetTimer;
76   -exports.clearInterval = unsetTimer;
  45 +exports.setTimeout = setTimer.bind(null, TYPE_ONE_SHOT);
  46 +exports.setInterval = setTimer.bind(null, TYPE_REPEATING_SLACK);
  47 +exports.clearTimeout = unsetTimer.bind(null);
  48 +exports.clearInterval = unsetTimer.bind(null);
77 49
78   -unload(function() { timers.forEach(unsetTimer); });
  50 +unload(function() { Object.keys(timers).forEach(unsetTimer) });

0 comments on commit 997d901

Please sign in to comment.
Something went wrong with that request. Please try again.