tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_devtoolschildremoved.html (16685B)


      1 <!doctype html>
      2 <html>
      3 <head>
      4 <meta charset="utf-8">
      5 <title>devtoolschildremoved event tests</title>
      6 <script src="/tests/SimpleTest/SimpleTest.js"></script>
      7 <script src="/tests/SimpleTest/EventUtils.js"></script>
      8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
      9 <script>
     10 "use strict";
     11 
     12 SimpleTest.waitForExplicitFinish();
     13 SimpleTest.waitForFocus(async () => {
     14  await SpecialPowers.pushPrefEnv({ set: [["dom.movebefore.enabled", true]] });
     15 
     16  // Unlock devtoolschildremoved events.
     17  SpecialPowers.wrap(document).devToolsWatchingDOMMutations = true;
     18  SimpleTest.registerCleanupFunction(() => {
     19    SpecialPowers.wrap(document).devToolsWatchingDOMMutations = false;
     20  });
     21 
     22  function getDevToolsChildRemovedEvent(aTarget, aTestBody, aOnEvent) {
     23    let event;
     24    function getEvent(e) {
     25      if (e.target == aTarget) {
     26        event = e;
     27        aOnEvent();
     28      }
     29    }
     30    const chromeEventHandler = SpecialPowers.wrap(window).docShell.chromeEventHandler;
     31    chromeEventHandler.addEventListener(
     32      "devtoolschildremoved",
     33      getEvent,
     34      {
     35        once: true,
     36        capture: true,
     37      }
     38    );
     39    try {
     40      aTestBody();
     41    } finally {
     42      chromeEventHandler.removeEventListener(
     43        "devtoolschildremoved",
     44        getEvent,
     45        {capture: true}
     46      );
     47    }
     48    return event;
     49  }
     50 
     51  const srcContainer = document.getElementById("container");
     52  const destContainer = document.getElementById("destContainer");
     53  const refChild = document.getElementById("refChild");
     54 
     55  // When a node is removed or moved from another place, "devtoolschildremoved"
     56  // event whose target is the removed node should be fired.
     57  {
     58    const span = document.createElement("span");
     59    srcContainer.appendChild(span);
     60    const event = getDevToolsChildRemovedEvent(
     61      span,
     62      () => {
     63        span.remove();
     64      },
     65      () => {
     66        is(
     67          span.parentNode,
     68          srcContainer,
     69          "devtoolschildremoved when Node.remove() should be called before removed from the DOM"
     70        );
     71      }
     72    );
     73    isnot(event, undefined, "Node.remove() should cause a devtoolschildremoved event");
     74  }
     75 
     76  {
     77    const span = document.createElement("span");
     78    srcContainer.appendChild(span);
     79    const event = getDevToolsChildRemovedEvent(
     80      span,
     81      () => {
     82        srcContainer.removeChild(span);
     83      },
     84      () => {
     85        is(
     86          span.parentNode,
     87          srcContainer,
     88          "devtoolschildremoved when Node.removeChild() should be called before removed from the DOM"
     89        );
     90      }
     91    );
     92    isnot(event, undefined, "Node.removeChild() should cause a devtoolschildremoved event");
     93  }
     94 
     95  {
     96    const span = document.createElement("span");
     97    srcContainer.appendChild(span);
     98    const event = getDevToolsChildRemovedEvent(
     99      span,
    100      () => {
    101        destContainer.appendChild(span);
    102      },
    103      () => {
    104        is(
    105          span.parentNode,
    106          srcContainer,
    107          "devtoolschildremoved when Node.appendChild() should be called before removed from the DOM"
    108        );
    109      }
    110    );
    111    isnot(event, undefined, "Node.appendChild() with connected node should cause a devtoolschildremoved event");
    112    span.remove();
    113  }
    114 
    115  {
    116    const span = document.createElement("span");
    117    srcContainer.appendChild(span);
    118    const event = getDevToolsChildRemovedEvent(
    119      span,
    120      () => {
    121        destContainer.insertBefore(span, refChild);
    122      },
    123      () => {
    124        is(
    125          span.parentNode,
    126          srcContainer,
    127          "devtoolschildremoved when Node.insertBefore() should be called before removed from the DOM"
    128        );
    129      }
    130    );
    131    isnot(event, undefined, "Node.insertBefore() with connected node should cause a devtoolschildremoved event");
    132    span.remove();
    133  }
    134 
    135  {
    136    const span = document.createElement("span");
    137    srcContainer.appendChild(span);
    138    const event = getDevToolsChildRemovedEvent(
    139      span,
    140      () => {
    141        destContainer.moveBefore(span, refChild);
    142      },
    143      () => {
    144        is(
    145          span.parentNode,
    146          srcContainer,
    147          "devtoolschildremoved when Node.moveBefore() should be called before removed from the DOM"
    148        );
    149      }
    150    );
    151    isnot(event, undefined, "Node.moveBefore() with connected node should cause a devtoolschildremoved event");
    152    span.remove();
    153  }
    154 
    155  // While DevTools breaks on a removal of a node, users can modify the DOM.
    156  // In such case, at least we should avoid to crash.
    157  {
    158    const span = document.createElement("span");
    159    srcContainer.appendChild(span);
    160    try {
    161      const event = getDevToolsChildRemovedEvent(
    162        span,
    163        () => {
    164          destContainer.appendChild(span);
    165        },
    166        () => {
    167          refChild.remove();
    168        }
    169      );
    170      isnot(
    171        event,
    172        undefined,
    173        "The dest container is modified while Node.appendChild() is called should cause a devtoolschildremoved event"
    174      );
    175    } catch (e) {
    176      is(
    177        span.parentNode,
    178        srcContainer,
    179        "The moving <span> should stay in the src container when the dest container is modified during Node.appendChild()"
    180      );
    181    } finally {
    182      span.remove();
    183      destContainer.appendChild(refChild);
    184    }
    185  }
    186 
    187  {
    188    const span = document.createElement("span");
    189    srcContainer.appendChild(span);
    190    try {
    191      const event = getDevToolsChildRemovedEvent(
    192        span,
    193        () => {
    194          destContainer.insertBefore(span, refChild);
    195        },
    196        () => {
    197          refChild.remove();
    198        }
    199      );
    200      isnot(
    201        event,
    202        undefined,
    203        "The dest container is modified while Node.insertBefore() is called should cause a devtoolschildremoved event"
    204      );
    205    } catch (e) {
    206      is(
    207        span.parentNode,
    208        srcContainer,
    209        "The moving <span> should stay in the src container when the dest container is modified during Node.insertBefore()"
    210      );
    211    } finally {
    212      span.remove();
    213      destContainer.appendChild(refChild);
    214    }
    215  }
    216 
    217  {
    218    const span = document.createElement("span");
    219    srcContainer.appendChild(span);
    220    try {
    221      const event = getDevToolsChildRemovedEvent(
    222        span,
    223        () => {
    224          destContainer.moveBefore(span, refChild);
    225        },
    226        () => {
    227          refChild.remove();
    228        }
    229      );
    230      isnot(
    231        event,
    232        undefined,
    233        "The dest container is modified while Node.moveBefore() is called should cause a devtoolschildremoved event"
    234      );
    235    } catch (e) {
    236      is(
    237        span.parentNode,
    238        srcContainer,
    239        "The moving <span> should stay in the src container when the dest container is modified during Node.moveBefore()"
    240      );
    241    } finally {
    242      span.remove();
    243      destContainer.appendChild(refChild);
    244    }
    245  }
    246 
    247  {
    248    const span = document.createElement("span");
    249    srcContainer.appendChild(span);
    250    try {
    251      const event = getDevToolsChildRemovedEvent(
    252        span,
    253        () => {
    254          destContainer.appendChild(span);
    255        },
    256        () => {
    257          destContainer.remove();
    258        }
    259      );
    260      isnot(
    261        event,
    262        undefined,
    263        "The dest container is removed while Node.appendChild() is called should cause a devtoolschildremoved event"
    264      );
    265    } catch (e) {
    266      is(
    267        span.parentNode,
    268        srcContainer,
    269        "The moving <span> should stay in the src container when the dest container is removed during Node.appendChild()"
    270      );
    271    } finally {
    272      span.remove();
    273      document.body.appendChild(destContainer);
    274    }
    275  }
    276 
    277  {
    278    const span = document.createElement("span");
    279    srcContainer.appendChild(span);
    280    try {
    281      const event = getDevToolsChildRemovedEvent(
    282        span,
    283        () => {
    284          destContainer.insertBefore(span, refChild);
    285        },
    286        () => {
    287          destContainer.remove();
    288        }
    289      );
    290      isnot(
    291        event,
    292        undefined,
    293        "The dest container is removed while Node.insertBefore() is called should cause a devtoolschildremoved event"
    294      );
    295    } catch (e) {
    296      is(
    297        span.parentNode,
    298        srcContainer,
    299        "The moving <span> should stay in the src container when the dest container is removed during Node.insertBefore()"
    300      );
    301    } finally {
    302      span.remove();
    303      document.body.appendChild(destContainer);
    304    }
    305  }
    306 
    307  {
    308    const span = document.createElement("span");
    309    srcContainer.appendChild(span);
    310    try {
    311      const event = getDevToolsChildRemovedEvent(
    312        span,
    313        () => {
    314          destContainer.moveBefore(span, refChild);
    315        },
    316        () => {
    317          destContainer.remove();
    318        }
    319      );
    320      isnot(
    321        event,
    322        undefined,
    323        "The dest container is removed while Node.moveBefore() is called should cause a devtoolschildremoved event"
    324      );
    325    } catch (e) {
    326      is(
    327        span.parentNode,
    328        srcContainer,
    329        "The moving <span> should stay in the src container when the dest container is removed during Node.moveBefore()"
    330      );
    331    } finally {
    332      span.remove();
    333      document.body.appendChild(destContainer);
    334    }
    335  }
    336 
    337  {
    338    const span = document.createElement("span");
    339    srcContainer.appendChild(span);
    340    try {
    341      const event = getDevToolsChildRemovedEvent(
    342        span,
    343        () => {
    344          span.remove();
    345        },
    346        () => {
    347          span.remove();
    348        }
    349      );
    350      isnot(
    351        event,
    352        undefined,
    353        "The removing <span> is removed while Node.remove() is called should cause a devtoolschildremoved event"
    354      );
    355    } catch (e) {
    356    } finally {
    357      is(
    358        span.parentNode,
    359        null,
    360        "The removing <span> should not stay in the src container when it's removed during Node.remove()"
    361      );
    362      span.remove();
    363    }
    364  }
    365 
    366  {
    367    const span = document.createElement("span");
    368    srcContainer.appendChild(span);
    369    try {
    370      const event = getDevToolsChildRemovedEvent(
    371        span,
    372        () => {
    373          srcContainer.removeChild(span);
    374        },
    375        () => {
    376          span.remove();
    377        }
    378      );
    379      isnot(
    380        event,
    381        undefined,
    382        "The removing <span> is removed while Node.removeChild() is called should cause a devtoolschildremoved event"
    383      );
    384    } catch (e) {
    385    } finally {
    386      is(
    387        span.parentNode,
    388        null,
    389        "The removing <span> should not stay in the src container when it's removed during Node.removeChild()"
    390      );
    391      span.remove();
    392    }
    393  }
    394 
    395  {
    396    const span = document.createElement("span");
    397    srcContainer.appendChild(span);
    398    try {
    399      const event = getDevToolsChildRemovedEvent(
    400        span,
    401        () => {
    402          destContainer.appendChild(span);
    403        },
    404        () => {
    405          span.remove();
    406        }
    407      );
    408      isnot(
    409        event,
    410        undefined,
    411        "The moving <span> is removed while Node.appendChild() is called should cause a devtoolschildremoved event"
    412      );
    413    } catch (e) {
    414      is(
    415        span.parentNode,
    416        null,
    417        "The moving <span> should not in the DOM when it's removed during Node.appendChild()"
    418      );
    419    } finally {
    420      span.remove();
    421    }
    422  }
    423 
    424  {
    425    const span = document.createElement("span");
    426    srcContainer.appendChild(span);
    427    try {
    428      const event = getDevToolsChildRemovedEvent(
    429        span,
    430        () => {
    431          destContainer.insertBefore(span, refChild);
    432        },
    433        () => {
    434          span.remove();
    435        }
    436      );
    437      isnot(
    438        event,
    439        undefined,
    440        "The moving <span> is removed while Node.insertBefore() is called should cause a devtoolschildremoved event"
    441      );
    442    } catch (e) {
    443      is(
    444        span.parentNode,
    445        null,
    446        "The moving <span> should not in the DOM when it's removed during Node.insertBefore()"
    447      );
    448    } finally {
    449      span.remove();
    450    }
    451  }
    452 
    453  {
    454    const span = document.createElement("span");
    455    srcContainer.appendChild(span);
    456    try {
    457      const event = getDevToolsChildRemovedEvent(
    458        span,
    459        () => {
    460          destContainer.moveBefore(span, refChild);
    461        },
    462        () => {
    463          span.remove();
    464        }
    465      );
    466      isnot(
    467        event,
    468        undefined,
    469        "The moving <span> is removed while Node.moveBefore() is called should cause a devtoolschildremoved event"
    470      );
    471    } catch (e) {
    472      is(
    473        span.parentNode,
    474        null,
    475        "The moving <span> should not in the DOM when it's removed during Node.moveBefore()"
    476      );
    477    } finally {
    478      span.remove();
    479    }
    480  }
    481 
    482  {
    483    const span = document.createElement("span");
    484    srcContainer.appendChild(span);
    485    try {
    486      const event = getDevToolsChildRemovedEvent(
    487        span,
    488        () => {
    489          span.remove();
    490        },
    491        () => {
    492          srcContainer.remove();
    493        }
    494      );
    495      isnot(
    496        event,
    497        undefined,
    498        "The src container is removed while Node.remove() is called should cause a devtoolschildremoved event"
    499      );
    500    } catch (e) {
    501      is(
    502        span.parentNode,
    503        srcContainer,
    504        "The removing <span> should stay in the src container when the container is removed during Node.remove()"
    505      );
    506    } finally {
    507      span.remove();
    508      document.body.insertBefore(srcContainer, destContainer);
    509    }
    510  }
    511 
    512  {
    513    const span = document.createElement("span");
    514    srcContainer.appendChild(span);
    515    try {
    516      const event = getDevToolsChildRemovedEvent(
    517        span,
    518        () => {
    519          srcContainer.removeChild(span);
    520        },
    521        () => {
    522          srcContainer.remove();
    523        }
    524      );
    525      isnot(
    526        event,
    527        undefined,
    528        "The src container is removed while Node.removeChild() is called should cause a devtoolschildremoved event"
    529      );
    530    } catch (e) {
    531      is(
    532        span.parentNode,
    533        srcContainer,
    534        "The removing <span> should stay in the src container when the container is removed during Node.removeChild()"
    535      );
    536    } finally {
    537      span.remove();
    538      document.body.insertBefore(srcContainer, destContainer);
    539    }
    540  }
    541 
    542  {
    543    const span = document.createElement("span");
    544    srcContainer.appendChild(span);
    545    try {
    546      const event = getDevToolsChildRemovedEvent(
    547        span,
    548        () => {
    549          destContainer.appendChild(span);
    550        },
    551        () => {
    552          srcContainer.remove();
    553        }
    554      );
    555      isnot(
    556        event,
    557        undefined,
    558        "The src container is removed while Node.appendChild() is called should cause a devtoolschildremoved event"
    559      );
    560    } catch (e) {
    561      is(
    562        span.parentNode,
    563        srcContainer,
    564        "The moving <span> should stay in the src container when the container is removed during Node.appendChild()"
    565      );
    566    } finally {
    567      span.remove();
    568      document.body.insertBefore(srcContainer, destContainer);
    569    }
    570  }
    571 
    572  {
    573    const span = document.createElement("span");
    574    srcContainer.appendChild(span);
    575    try {
    576      const event = getDevToolsChildRemovedEvent(
    577        span,
    578        () => {
    579          destContainer.insertBefore(span, refChild);
    580        },
    581        () => {
    582          srcContainer.remove();
    583        }
    584      );
    585      isnot(
    586        event,
    587        undefined,
    588        "The src container is removed while Node.insertBefore() is called should cause a devtoolschildremoved event"
    589      );
    590    } catch (e) {
    591      is(
    592        span.parentNode,
    593        srcContainer,
    594        "The moving <span> should stay in the src container when the container is removed during Node.insertBefore()"
    595      );
    596    } finally {
    597      span.remove();
    598      document.body.insertBefore(srcContainer, destContainer);
    599    }
    600  }
    601 
    602  {
    603    const span = document.createElement("span");
    604    srcContainer.appendChild(span);
    605    try {
    606      const event = getDevToolsChildRemovedEvent(
    607        span,
    608        () => {
    609          destContainer.moveBefore(span, refChild);
    610        },
    611        () => {
    612          srcContainer.remove();
    613        }
    614      );
    615      isnot(
    616        event,
    617        undefined,
    618        "The src container is removed while Node.moveBefore() is called should cause a devtoolschildremoved event"
    619      );
    620    } catch (e) {
    621      is(
    622        span.parentNode,
    623        srcContainer,
    624        "The moving <span> should stay in the src container when the container is removed during Node.moveBefore()"
    625      );
    626    } finally {
    627      span.remove();
    628      document.body.insertBefore(srcContainer, destContainer);
    629    }
    630  }
    631 
    632  SimpleTest.finish();
    633 });
    634 </script>
    635 </head>
    636 <body>
    637  <div id="container"></div>
    638  <div id="destContainer"><span id="refChild"></span></div>
    639 </body>
    640 </html>