browser/devtools/debugger/test/browser_dbg_variables-view-accessibility.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 /**
     5  * Make sure that the variables view is keyboard accessible.
     6  */
     8 let gTab, gDebuggee, gPanel, gDebugger;
     9 let gVariablesView;
    11 function test() {
    12   initDebugger("about:blank").then(([aTab, aDebuggee, aPanel]) => {
    13     gTab = aTab;
    14     gDebuggee = aDebuggee;
    15     gPanel = aPanel;
    16     gDebugger = gPanel.panelWin;
    17     gVariablesView = gDebugger.DebuggerView.Variables;
    19     performTest().then(null, aError => {
    20       ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
    21     });
    22   });
    23 }
    25 function performTest() {
    26   let arr = [
    27     42,
    28     true,
    29     "nasu",
    30     undefined,
    31     null,
    32     [0, 1, 2],
    33     { prop1: 9, prop2: 8 }
    34   ];
    36   let obj = {
    37     p0: 42,
    38     p1: true,
    39     p2: "nasu",
    40     p3: undefined,
    41     p4: null,
    42     p5: [3, 4, 5],
    43     p6: { prop1: 7, prop2: 6 },
    44     get p7() { return arr; },
    45     set p8(value) { arr[0] = value }
    46   };
    48   let test = {
    49     someProp0: 42,
    50     someProp1: true,
    51     someProp2: "nasu",
    52     someProp3: undefined,
    53     someProp4: null,
    54     someProp5: arr,
    55     someProp6: obj,
    56     get someProp7() { return arr; },
    57     set someProp7(value) { arr[0] = value }
    58   };
    60   gVariablesView.eval = function() {};
    61   gVariablesView.switch = function() {};
    62   gVariablesView.delete = function() {};
    63   gVariablesView.rawObject = test;
    64   gVariablesView.scrollPageSize = 5;
    66   return Task.spawn(function() {
    67     yield waitForTick();
    69     // Part 0: Test generic focus methods on the variables view.
    71     gVariablesView.focusFirstVisibleItem();
    72     is(gVariablesView.getFocusedItem().name, "someProp0",
    73       "The 'someProp0' item should be focused.");
    75     gVariablesView.focusNextItem();
    76     is(gVariablesView.getFocusedItem().name, "someProp1",
    77       "The 'someProp1' item should be focused.");
    79     gVariablesView.focusPrevItem();
    80     is(gVariablesView.getFocusedItem().name, "someProp0",
    81       "The 'someProp0' item should be focused.");
    83     // Part 1: Make sure that UP/DOWN keys don't scroll the variables view.
    85     yield synthesizeKeyAndWaitForTick("VK_DOWN", {});
    86     is(gVariablesView._parent.scrollTop, 0,
    87       "The 'variables' view shouldn't scroll when pressing the DOWN key.");
    89     yield synthesizeKeyAndWaitForTick("VK_UP", {});
    90     is(gVariablesView._parent.scrollTop, 0,
    91       "The 'variables' view shouldn't scroll when pressing the UP key.");
    93     // Part 2: Make sure that RETURN/ESCAPE toggle input elements.
    95     yield synthesizeKeyAndWaitForElement("VK_RETURN", {}, ".element-value-input", true);
    96     yield synthesizeKeyAndWaitForElement("VK_ESCAPE", {}, ".element-value-input", false);
    97     yield synthesizeKeyAndWaitForElement("VK_RETURN", { shiftKey: true }, ".element-name-input", true);
    98     yield synthesizeKeyAndWaitForElement("VK_ESCAPE", {}, ".element-name-input", false);
   100     // Part 3: Test simple navigation.
   102     EventUtils.sendKey("DOWN", gDebugger);
   103     is(gVariablesView.getFocusedItem().name, "someProp1",
   104       "The 'someProp1' item should be focused.");
   106     EventUtils.sendKey("UP", gDebugger);
   107     is(gVariablesView.getFocusedItem().name, "someProp0",
   108       "The 'someProp0' item should be focused.");
   110     EventUtils.sendKey("PAGE_DOWN", gDebugger);
   111     is(gVariablesView.getFocusedItem().name, "someProp5",
   112       "The 'someProp5' item should be focused.");
   114     EventUtils.sendKey("PAGE_UP", gDebugger);
   115     is(gVariablesView.getFocusedItem().name, "someProp0",
   116       "The 'someProp0' item should be focused.");
   118     EventUtils.sendKey("END", gDebugger);
   119     is(gVariablesView.getFocusedItem().name, "__proto__",
   120       "The '__proto__' item should be focused.");
   122     EventUtils.sendKey("HOME", gDebugger);
   123     is(gVariablesView.getFocusedItem().name, "someProp0",
   124       "The 'someProp0' item should be focused.");
   126     // Part 4: Test if pressing the same navigation key twice works as expected.
   128     EventUtils.sendKey("DOWN", gDebugger);
   129     is(gVariablesView.getFocusedItem().name, "someProp1",
   130       "The 'someProp1' item should be focused.");
   132     EventUtils.sendKey("DOWN", gDebugger);
   133     is(gVariablesView.getFocusedItem().name, "someProp2",
   134       "The 'someProp2' item should be focused.");
   136     EventUtils.sendKey("UP", gDebugger);
   137     is(gVariablesView.getFocusedItem().name, "someProp1",
   138       "The 'someProp1' item should be focused.");
   140     EventUtils.sendKey("UP", gDebugger);
   141     is(gVariablesView.getFocusedItem().name, "someProp0",
   142       "The 'someProp0' item should be focused.");
   144     EventUtils.sendKey("PAGE_DOWN", gDebugger);
   145     is(gVariablesView.getFocusedItem().name, "someProp5",
   146       "The 'someProp5' item should be focused.");
   148     EventUtils.sendKey("PAGE_DOWN", gDebugger);
   149     is(gVariablesView.getFocusedItem().name, "__proto__",
   150       "The '__proto__' item should be focused.");
   152     EventUtils.sendKey("PAGE_UP", gDebugger);
   153     is(gVariablesView.getFocusedItem().name, "someProp5",
   154       "The 'someProp5' item should be focused.");
   156     EventUtils.sendKey("PAGE_UP", gDebugger);
   157     is(gVariablesView.getFocusedItem().name, "someProp0",
   158       "The 'someProp0' item should be focused.");
   160     // Part 5: Test that HOME/PAGE_UP/PAGE_DOWN are symmetrical.
   162     EventUtils.sendKey("HOME", gDebugger);
   163     is(gVariablesView.getFocusedItem().name, "someProp0",
   164       "The 'someProp0' item should be focused.");
   166     EventUtils.sendKey("HOME", gDebugger);
   167     is(gVariablesView.getFocusedItem().name, "someProp0",
   168       "The 'someProp0' item should be focused.");
   170     EventUtils.sendKey("PAGE_UP", gDebugger);
   171     is(gVariablesView.getFocusedItem().name, "someProp0",
   172       "The 'someProp0' item should be focused.");
   174     EventUtils.sendKey("HOME", gDebugger);
   175     is(gVariablesView.getFocusedItem().name, "someProp0",
   176       "The 'someProp0' item should be focused.");
   178     EventUtils.sendKey("END", gDebugger);
   179     is(gVariablesView.getFocusedItem().name, "__proto__",
   180       "The '__proto__' item should be focused.");
   182     EventUtils.sendKey("END", gDebugger);
   183     is(gVariablesView.getFocusedItem().name, "__proto__",
   184       "The '__proto__' item should be focused.");
   186     EventUtils.sendKey("PAGE_DOWN", gDebugger);
   187     is(gVariablesView.getFocusedItem().name, "__proto__",
   188       "The '__proto__' item should be focused.");
   190     EventUtils.sendKey("END", gDebugger);
   191     is(gVariablesView.getFocusedItem().name, "__proto__",
   192       "The '__proto__' item should be focused.");
   194     // Part 6: Test that focus doesn't leave the variables view.
   196     EventUtils.sendKey("PAGE_UP", gDebugger);
   197     is(gVariablesView.getFocusedItem().name, "someProp5",
   198       "The 'someProp5' item should be focused.");
   200     EventUtils.sendKey("PAGE_UP", gDebugger);
   201     is(gVariablesView.getFocusedItem().name, "someProp0",
   202       "The 'someProp0' item should be focused.");
   204     EventUtils.sendKey("UP", gDebugger);
   205     is(gVariablesView.getFocusedItem().name, "someProp0",
   206       "The 'someProp0' item should be focused.");
   208     EventUtils.sendKey("UP", gDebugger);
   209     is(gVariablesView.getFocusedItem().name, "someProp0",
   210       "The 'someProp0' item should be focused.");
   212     EventUtils.sendKey("PAGE_DOWN", gDebugger);
   213     is(gVariablesView.getFocusedItem().name, "someProp5",
   214       "The 'someProp5' item should be focused.");
   216     EventUtils.sendKey("PAGE_DOWN", gDebugger);
   217     is(gVariablesView.getFocusedItem().name, "__proto__",
   218       "The '__proto__' item should be focused.");
   220     EventUtils.sendKey("PAGE_DOWN", gDebugger);
   221     is(gVariablesView.getFocusedItem().name, "__proto__",
   222       "The '__proto__' item should be focused.");
   224     EventUtils.sendKey("PAGE_DOWN", gDebugger);
   225     is(gVariablesView.getFocusedItem().name, "__proto__",
   226       "The '__proto__' item should be focused.");
   228     // Part 7: Test that random offsets don't occur in tandem with HOME/END.
   230     EventUtils.sendKey("HOME", gDebugger);
   231     is(gVariablesView.getFocusedItem().name, "someProp0",
   232       "The 'someProp0' item should be focused.");
   234     EventUtils.sendKey("DOWN", gDebugger);
   235     is(gVariablesView.getFocusedItem().name, "someProp1",
   236       "The 'someProp1' item should be focused.");
   238     EventUtils.sendKey("END", gDebugger);
   239     is(gVariablesView.getFocusedItem().name, "__proto__",
   240       "The '__proto__' item should be focused.");
   242     EventUtils.sendKey("DOWN", gDebugger);
   243     is(gVariablesView.getFocusedItem().name, "__proto__",
   244       "The '__proto__' item should be focused.");
   246     // Part 8: Test that the RIGHT key expands elements as intended.
   248     EventUtils.sendKey("PAGE_UP", gDebugger);
   249     is(gVariablesView.getFocusedItem().name, "someProp5",
   250       "The 'someProp5' item should be focused.");
   251     is(gVariablesView.getFocusedItem().expanded, false,
   252       "The 'someProp5' item should not be expanded yet.");
   254     yield synthesizeKeyAndWaitForTick("VK_RIGHT", {});
   255     is(gVariablesView.getFocusedItem().name, "someProp5",
   256       "The 'someProp5' item should be focused.");
   257     is(gVariablesView.getFocusedItem().expanded, true,
   258       "The 'someProp5' item should now be expanded.");
   259     is(gVariablesView.getFocusedItem()._store.size, 9,
   260       "There should be 9 properties in the selected variable.");
   261     is(gVariablesView.getFocusedItem()._enumItems.length, 7,
   262       "There should be 7 enumerable properties in the selected variable.");
   263     is(gVariablesView.getFocusedItem()._nonEnumItems.length, 2,
   264       "There should be 2 non-enumerable properties in the selected variable.");
   266     yield waitForChildNodes(gVariablesView.getFocusedItem()._enum, 7);
   267     yield waitForChildNodes(gVariablesView.getFocusedItem()._nonenum, 2);
   269     EventUtils.sendKey("RIGHT", gDebugger);
   270     is(gVariablesView.getFocusedItem().name, "0",
   271       "The '0' item should be focused.");
   273     EventUtils.sendKey("RIGHT", gDebugger);
   274     is(gVariablesView.getFocusedItem().name, "0",
   275       "The '0' item should still be focused.");
   277     EventUtils.sendKey("PAGE_DOWN", gDebugger);
   278     is(gVariablesView.getFocusedItem().name, "5",
   279       "The '5' item should be focused.");
   280     is(gVariablesView.getFocusedItem().expanded, false,
   281       "The '5' item should not be expanded yet.");
   283     yield synthesizeKeyAndWaitForTick("VK_RIGHT", {});
   284     is(gVariablesView.getFocusedItem().name, "5",
   285       "The '5' item should be focused.");
   286     is(gVariablesView.getFocusedItem().expanded, true,
   287       "The '5' item should now be expanded.");
   288     is(gVariablesView.getFocusedItem()._store.size, 5,
   289       "There should be 5 properties in the selected variable.");
   290     is(gVariablesView.getFocusedItem()._enumItems.length, 3,
   291       "There should be 3 enumerable properties in the selected variable.");
   292     is(gVariablesView.getFocusedItem()._nonEnumItems.length, 2,
   293       "There should be 2 non-enumerable properties in the selected variable.");
   295     yield waitForChildNodes(gVariablesView.getFocusedItem()._enum, 3);
   296     yield waitForChildNodes(gVariablesView.getFocusedItem()._nonenum, 2);
   298     EventUtils.sendKey("RIGHT", gDebugger);
   299     is(gVariablesView.getFocusedItem().name, "0",
   300       "The '0' item should be focused.");
   302     EventUtils.sendKey("RIGHT", gDebugger);
   303     is(gVariablesView.getFocusedItem().name, "0",
   304       "The '0' item should still be focused.");
   306     EventUtils.sendKey("PAGE_DOWN", gDebugger);
   307     is(gVariablesView.getFocusedItem().name, "6",
   308       "The '6' item should be focused.");
   309     is(gVariablesView.getFocusedItem().expanded, false,
   310       "The '6' item should not be expanded yet.");
   312     yield synthesizeKeyAndWaitForTick("VK_RIGHT", {});
   313     is(gVariablesView.getFocusedItem().name, "6",
   314       "The '6' item should be focused.");
   315     is(gVariablesView.getFocusedItem().expanded, true,
   316       "The '6' item should now be expanded.");
   317     is(gVariablesView.getFocusedItem()._store.size, 3,
   318       "There should be 3 properties in the selected variable.");
   319     is(gVariablesView.getFocusedItem()._enumItems.length, 2,
   320       "There should be 2 enumerable properties in the selected variable.");
   321     is(gVariablesView.getFocusedItem()._nonEnumItems.length, 1,
   322       "There should be 1 non-enumerable properties in the selected variable.");
   324     yield waitForChildNodes(gVariablesView.getFocusedItem()._enum, 2);
   325     yield waitForChildNodes(gVariablesView.getFocusedItem()._nonenum, 1);
   327     EventUtils.sendKey("RIGHT", gDebugger);
   328     is(gVariablesView.getFocusedItem().name, "prop1",
   329       "The 'prop1' item should be focused.");
   331     EventUtils.sendKey("RIGHT", gDebugger);
   332     is(gVariablesView.getFocusedItem().name, "prop1",
   333       "The 'prop1' item should still be focused.");
   335     EventUtils.sendKey("PAGE_DOWN", gDebugger);
   336     is(gVariablesView.getFocusedItem().name, "someProp6",
   337       "The 'someProp6' item should be focused.");
   338     is(gVariablesView.getFocusedItem().expanded, false,
   339       "The 'someProp6' item should not be expanded yet.");
   341     // Part 9: Test that the RIGHT key collapses elements as intended.
   343     EventUtils.sendKey("LEFT", gDebugger);
   344     is(gVariablesView.getFocusedItem().name, "someProp6",
   345       "The 'someProp6' item should be focused.");
   347     EventUtils.sendKey("UP", gDebugger);
   348     is(gVariablesView.getFocusedItem().name, "__proto__",
   349       "The '__proto__' item should be focused.");
   351     EventUtils.sendKey("LEFT", gDebugger);
   352     is(gVariablesView.getFocusedItem().name, "someProp5",
   353       "The 'someProp5' item should be focused.");
   354     is(gVariablesView.getFocusedItem().expanded, true,
   355       "The '6' item should still be expanded.");
   357     EventUtils.sendKey("LEFT", gDebugger);
   358     is(gVariablesView.getFocusedItem().name, "someProp5",
   359       "The 'someProp5' item should still be focused.");
   360     is(gVariablesView.getFocusedItem().expanded, false,
   361       "The '6' item should still not be expanded anymore.");
   363     EventUtils.sendKey("LEFT", gDebugger);
   364     is(gVariablesView.getFocusedItem().name, "someProp5",
   365       "The 'someProp5' item should still be focused.");
   367     // Part 9: Test continuous navigation.
   369     EventUtils.sendKey("UP", gDebugger);
   370     is(gVariablesView.getFocusedItem().name, "someProp4",
   371       "The 'someProp4' item should be focused.");
   373     EventUtils.sendKey("UP", gDebugger);
   374     is(gVariablesView.getFocusedItem().name, "someProp3",
   375       "The 'someProp3' item should be focused.");
   377     EventUtils.sendKey("UP", gDebugger);
   378     is(gVariablesView.getFocusedItem().name, "someProp2",
   379       "The 'someProp2' item should be focused.");
   381     EventUtils.sendKey("UP", gDebugger);
   382     is(gVariablesView.getFocusedItem().name, "someProp1",
   383       "The 'someProp1' item should be focused.");
   385     EventUtils.sendKey("UP", gDebugger);
   386     is(gVariablesView.getFocusedItem().name, "someProp0",
   387       "The 'someProp0' item should be focused.");
   389     EventUtils.sendKey("PAGE_UP", gDebugger);
   390     is(gVariablesView.getFocusedItem().name, "someProp0",
   391       "The 'someProp0' item should be focused.");
   393     EventUtils.sendKey("PAGE_DOWN", gDebugger);
   394     is(gVariablesView.getFocusedItem().name, "someProp5",
   395       "The 'someProp5' item should be focused.");
   397     EventUtils.sendKey("DOWN", gDebugger);
   398     is(gVariablesView.getFocusedItem().name, "someProp6",
   399       "The 'someProp6' item should be focused.");
   401     EventUtils.sendKey("DOWN", gDebugger);
   402     is(gVariablesView.getFocusedItem().name, "someProp7",
   403       "The 'someProp7' item should be focused.");
   405     EventUtils.sendKey("DOWN", gDebugger);
   406     is(gVariablesView.getFocusedItem().name, "get",
   407       "The 'get' item should be focused.");
   409     EventUtils.sendKey("DOWN", gDebugger);
   410     is(gVariablesView.getFocusedItem().name, "set",
   411       "The 'set' item should be focused.");
   413     EventUtils.sendKey("DOWN", gDebugger);
   414     is(gVariablesView.getFocusedItem().name, "__proto__",
   415       "The '__proto__' item should be focused.");
   417     // Part 10: Test that BACKSPACE deletes items in the variables view.
   419     EventUtils.sendKey("BACK_SPACE", gDebugger);
   420     is(gVariablesView.getFocusedItem().name, "__proto__",
   421       "The '__proto__' variable should still be focused.");
   422     is(gVariablesView.getFocusedItem().value, "[object Object]",
   423       "The '__proto__' variable should not have an empty value.");
   424     is(gVariablesView.getFocusedItem().visible, false,
   425       "The '__proto__' variable should be hidden.");
   427     EventUtils.sendKey("UP", gDebugger);
   428     is(gVariablesView.getFocusedItem().name, "set",
   429       "The 'set' item should be focused.");
   430     is(gVariablesView.getFocusedItem().value, "[object Object]",
   431       "The 'set' item should not have an empty value.");
   432     is(gVariablesView.getFocusedItem().visible, true,
   433       "The 'set' item should be visible.");
   435     EventUtils.sendKey("BACK_SPACE", gDebugger);
   436     is(gVariablesView.getFocusedItem().name, "set",
   437       "The 'set' item should still be focused.");
   438     is(gVariablesView.getFocusedItem().value, "[object Object]",
   439       "The 'set' item should not have an empty value.");
   440     is(gVariablesView.getFocusedItem().visible, true,
   441       "The 'set' item should be visible.");
   442     is(gVariablesView.getFocusedItem().twisty, false,
   443       "The 'set' item should be disabled and have a hidden twisty.");
   445     EventUtils.sendKey("UP", gDebugger);
   446     is(gVariablesView.getFocusedItem().name, "get",
   447       "The 'get' item should be focused.");
   448     is(gVariablesView.getFocusedItem().value, "[object Object]",
   449       "The 'get' item should not have an empty value.");
   450     is(gVariablesView.getFocusedItem().visible, true,
   451       "The 'get' item should be visible.");
   453     EventUtils.sendKey("BACK_SPACE", gDebugger);
   454     is(gVariablesView.getFocusedItem().name, "get",
   455       "The 'get' item should still be focused.");
   456     is(gVariablesView.getFocusedItem().value, "[object Object]",
   457       "The 'get' item should not have an empty value.");
   458     is(gVariablesView.getFocusedItem().visible, true,
   459       "The 'get' item should be visible.");
   460     is(gVariablesView.getFocusedItem().twisty, false,
   461       "The 'get' item should be disabled and have a hidden twisty.");
   463     EventUtils.sendKey("UP", gDebugger);
   464     is(gVariablesView.getFocusedItem().name, "someProp7",
   465       "The 'someProp7' item should be focused.");
   466     is(gVariablesView.getFocusedItem().value, undefined,
   467       "The 'someProp7' variable should have an empty value.");
   468     is(gVariablesView.getFocusedItem().visible, true,
   469       "The 'someProp7' variable should be visible.");
   471     EventUtils.sendKey("BACK_SPACE", gDebugger);
   472     is(gVariablesView.getFocusedItem().name, "someProp7",
   473       "The 'someProp7' variable should still be focused.");
   474     is(gVariablesView.getFocusedItem().value, undefined,
   475       "The 'someProp7' variable should have an empty value.");
   476     is(gVariablesView.getFocusedItem().visible, false,
   477       "The 'someProp7' variable should be hidden.");
   479     // Part 11: Test that Ctrl-C copies the current item to the system clipboard
   481     gVariablesView.focusFirstVisibleItem();
   482     let copied = promise.defer();
   483     let expectedValue = gVariablesView.getFocusedItem().name
   484       + gVariablesView.getFocusedItem().separatorStr
   485       + gVariablesView.getFocusedItem().value;
   487     waitForClipboard(expectedValue, function setup() {
   488         EventUtils.synthesizeKey("C", { metaKey: true }, gDebugger);
   489       }, copied.resolve, copied.reject
   490     );
   492     try {
   493       yield copied.promise;
   494       ok(true,
   495         "Ctrl-C copied the selected item to the clipboard.");
   496     } catch (e) {
   497       ok(false,
   498         "Ctrl-C didn't copy the selected item to the clipboard.");
   499     }
   501     yield closeDebuggerAndFinish(gPanel);
   502   });
   503 }
   505 registerCleanupFunction(function() {
   506   gTab = null;
   507   gDebuggee = null;
   508   gPanel = null;
   509   gDebugger = null;
   510   gVariablesView = null;
   511 });
   513 function synthesizeKeyAndWaitForElement(aKey, aModifiers, aSelector, aExistence) {
   514   EventUtils.synthesizeKey(aKey, aModifiers, gDebugger);
   515   return waitForElement(aSelector, aExistence);
   516 }
   518 function synthesizeKeyAndWaitForTick(aKey, aModifiers) {
   519   EventUtils.synthesizeKey(aKey, aModifiers, gDebugger);
   520   return waitForTick();
   521 }
   523 function waitForElement(aSelector, aExistence) {
   524   return waitForPredicate(() => {
   525     return !!gVariablesView._list.querySelector(aSelector) == aExistence;
   526   });
   527 }
   529 function waitForChildNodes(aTarget, aCount) {
   530   return waitForPredicate(() => {
   531     return aTarget.childNodes.length == aCount;
   532   });
   533 }
   535 function waitForPredicate(aPredicate, aInterval = 10) {
   536   let deferred = promise.defer();
   538   // Poll every few milliseconds until the element is retrieved.
   539   let count = 0;
   540   let intervalID = window.setInterval(() => {
   541     // Make sure we don't wait for too long.
   542     if (++count > 1000) {
   543       deferred.reject("Timed out while polling for the element.");
   544       window.clearInterval(intervalID);
   545       return;
   546     }
   547     // Check if the predicate condition is fulfilled.
   548     if (!aPredicate()) {
   549       return;
   550     }
   551     // We got the element, it's safe to callback.
   552     window.clearInterval(intervalID);
   553     deferred.resolve();
   554   }, aInterval);
   556   return deferred.promise;
   557 }

mercurial