tor-browser

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

join-different-white-space-style-paragraphs.html (22309B)


      1 <!doctype html>
      2 <head>
      3 <meta charset="utf-8">
      4 <meta name="timeout" content="long">
      5 <meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=pre">
      6 <meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=pre-wrap">
      7 <meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=pre-line">
      8 <meta name="variant" content="?method=backspace&left-white-space=normal&right-white-space=nowrap">
      9 <meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=normal">
     10 <meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=pre-wrap">
     11 <meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=pre-line">
     12 <meta name="variant" content="?method=backspace&left-white-space=pre&right-white-space=nowrap">
     13 <meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=normal">
     14 <meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=pre">
     15 <meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=pre-line">
     16 <meta name="variant" content="?method=backspace&left-white-space=pre-wrap&right-white-space=nowrap">
     17 <meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=normal">
     18 <meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=pre">
     19 <meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=pre-wrap">
     20 <meta name="variant" content="?method=backspace&left-white-space=pre-line&right-white-space=nowrap">
     21 <meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=normal">
     22 <meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=pre">
     23 <meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=pre-wrap">
     24 <meta name="variant" content="?method=backspace&left-white-space=nowrap&right-white-space=pre-line">
     25 
     26 <meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=pre">
     27 <meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=pre-wrap">
     28 <meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=pre-line">
     29 <meta name="variant" content="?method=forwarddelete&left-white-space=normal&right-white-space=nowrap">
     30 <meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=normal">
     31 <meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=pre-wrap">
     32 <meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=pre-line">
     33 <meta name="variant" content="?method=forwarddelete&left-white-space=pre&right-white-space=nowrap">
     34 <meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=normal">
     35 <meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=pre">
     36 <meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=pre-line">
     37 <meta name="variant" content="?method=forwarddelete&left-white-space=pre-wrap&right-white-space=nowrap">
     38 <meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=normal">
     39 <meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=pre">
     40 <meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=pre-wrap">
     41 <meta name="variant" content="?method=forwarddelete&left-white-space=pre-line&right-white-space=nowrap">
     42 <meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=normal">
     43 <meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=pre">
     44 <meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=pre-wrap">
     45 <meta name="variant" content="?method=forwarddelete&left-white-space=nowrap&right-white-space=pre-line">
     46 
     47 <meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=pre">
     48 <meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=pre-wrap">
     49 <meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=pre-line">
     50 <meta name="variant" content="?method=select-boundary&left-white-space=normal&right-white-space=nowrap">
     51 <meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=normal">
     52 <meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=pre-wrap">
     53 <meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=pre-line">
     54 <meta name="variant" content="?method=select-boundary&left-white-space=pre&right-white-space=nowrap">
     55 <meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=normal">
     56 <meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=pre">
     57 <meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=pre-line">
     58 <meta name="variant" content="?method=select-boundary&left-white-space=pre-wrap&right-white-space=nowrap">
     59 <meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=normal">
     60 <meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=pre">
     61 <meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=pre-wrap">
     62 <meta name="variant" content="?method=select-boundary&left-white-space=pre-line&right-white-space=nowrap">
     63 <meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=normal">
     64 <meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=pre">
     65 <meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=pre-wrap">
     66 <meta name="variant" content="?method=select-boundary&left-white-space=nowrap&right-white-space=pre-line">
     67 <title>Tests for joining paragraphs which have different white-space styles</title>
     68 <script src="/resources/testharness.js"></script>
     69 <script src="/resources/testharnessreport.js"></script>
     70 <script src="/resources/testdriver.js"></script>
     71 <script src="/resources/testdriver-vendor.js"></script>
     72 <script src="/resources/testdriver-actions.js"></script>
     73 <script src="../include/editor-test-utils.js"></script>
     74 <style>
     75 .pre {
     76  white-space: pre;
     77 }
     78 .preWrap {
     79  white-space: pre-wrap;
     80 }
     81 .preLine {
     82  white-space: pre-line;
     83 }
     84 .nowrap {
     85  white-space: nowrap;
     86 }
     87 </style>
     88 </head>
     89 <body>
     90 <div contenteditable></div>
     91 <script>
     92 "use strict";
     93 
     94 const searchParams = new URLSearchParams(document.location.search);
     95 const testingBackspace = searchParams.get("method") == "backspace";
     96 const testingSelectBoundary = searchParams.get("method") == "select-boundary";
     97 const commandName =
     98  testingBackspace || testingSelectBoundary ? "delete" : "forwarddelete";
     99 const editingHost = document.querySelector("div[contenteditable]");
    100 const caretInLeft = (() => {
    101  if (testingSelectBoundary) {
    102    return "[";
    103  }
    104  return testingBackspace ? "" : "[]";
    105 })();
    106 const caretInRight = (() => {
    107  if (testingSelectBoundary) {
    108    return "]";
    109  }
    110  return testingBackspace ? "[]" : "";
    111 })();
    112 const leftWhiteSpace = `white-space:${searchParams.get("left-white-space")}`;
    113 const rightWhiteSpace = `white-space:${searchParams.get("right-white-space")}`;
    114 const leftWhiteSpacePreserveLineBreaks =
    115  searchParams.get("left-white-space") == "pre" ||
    116  searchParams.get("left-white-space") == "pre-wrap" ||
    117  searchParams.get("left-white-space") == "pre-line";
    118 const rightWhiteSpacePreserveLineBreaks =
    119  searchParams.get("right-white-space") == "pre" ||
    120  searchParams.get("right-white-space") == "pre-wrap" ||
    121  searchParams.get("right-white-space") == "pre-line";
    122 const leftWhiteSpaceClass = (() => {
    123  switch (searchParams.get("left-white-space")) {
    124    case "pre":
    125      return "pre";
    126    case "pre-wrap":
    127      return "preWrap";
    128    case "pre-line":
    129      return "preLine";
    130    case "nowrap":
    131      return "nowrap";
    132    default:
    133      return null;
    134  }
    135 })();
    136 const rightWhiteSpaceClass = (() => {
    137  switch (searchParams.get("right-white-space")) {
    138    case "pre":
    139      return "pre";
    140    case "pre-wrap":
    141      return "preWrap";
    142    case "pre-line":
    143      return "preLine";
    144    case "nowrap":
    145      return "nowrap";
    146    default:
    147      return null;
    148  }
    149 })();
    150 const utils = new EditorTestUtils(editingHost);
    151 
    152 const tests = [
    153  {
    154    initialHTML:
    155      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    156        `<div style="${rightWhiteSpace}">${caretInRight}def</div>`,
    157    expectedHTML: aAttrsInLeftBlock => {
    158      return [
    159        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>`,
    160      ];
    161    },
    162  },
    163  // Only first line of the right paragraph should be merged into the left paragraph.
    164  {
    165    initialHTML:
    166      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    167        `<div style="${rightWhiteSpace}">${caretInRight}def\nghi</div>`,
    168    expectedHTML: aAttrsInLeftBlock => {
    169      return [
    170        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` +
    171          `<div style="${rightWhiteSpace}">ghi</div>`,
    172      ];
    173    },
    174    skip: !rightWhiteSpacePreserveLineBreaks,
    175  },
    176  {
    177    initialHTML:
    178      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    179        `<div style="${rightWhiteSpace}">${caretInRight}def<br>ghi</div>`,
    180    expectedHTML: aAttrsInLeftBlock => {
    181      return [
    182        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` +
    183          `<div style="${rightWhiteSpace}">ghi</div>`,
    184      ];
    185    },
    186  },
    187  // `white-space` should be preserved with <b>.
    188  {
    189    initialHTML:
    190      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    191        `<div style="${rightWhiteSpace}"><b>${caretInRight}def\nghi</b></div>`,
    192    expectedHTML: aAttrsInLeftBlock => {
    193      return [
    194        `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` +
    195          `<div style="${rightWhiteSpace}"><b>ghi</b></div>`,
    196        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` +
    197          `<div style="${rightWhiteSpace}"><b>ghi</b></div>`,
    198      ];
    199    },
    200    skip: !rightWhiteSpacePreserveLineBreaks,
    201  },
    202  {
    203    initialHTML:
    204      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    205        `<div style="${rightWhiteSpace}"><b>${caretInRight}def<br>ghi</b></div>`,
    206    expectedHTML: aAttrsInLeftBlock => {
    207      return [
    208        `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` +
    209          `<div style="${rightWhiteSpace}"><b>ghi</b></div>`,
    210        `<div style="${leftWhiteSpace}">abc<span  ${aAttrsInLeftBlock}><b ${aAttrsInLeftBlock}>def</b></span></div>` +
    211          `<div style="${rightWhiteSpace}"><b>ghi</b></div>`,
    212      ];
    213    },
    214  },
    215  // `white-space` should be preserved with <b> as far as possible, and create <span> for no container part.
    216  {
    217    initialHTML:
    218      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    219        `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b>ghi\njkl</div>`,
    220    expectedHTML: aAttrsInLeftBlock => {
    221      return [
    222        `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b><span ${aAttrsInLeftBlock}>ghi</span></div>` +
    223          `<div style="${rightWhiteSpace}">jkl</div>`,
    224        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b>ghi</span></div>` +
    225          `<div style="${rightWhiteSpace}">jkl</div>`,
    226      ];
    227    },
    228    skip: !rightWhiteSpacePreserveLineBreaks,
    229  },
    230  {
    231    initialHTML:
    232      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    233        `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b>ghi<br>jkl</div>`,
    234    expectedHTML: aAttrsInLeftBlock => {
    235      return [
    236        `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b><span ${aAttrsInLeftBlock}>ghi</span></div>` +
    237          `<div style="${rightWhiteSpace}">jkl</div>`,
    238        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b>ghi</span></div>` +
    239          `<div style="${rightWhiteSpace}">jkl</div>`,
    240      ];
    241    },
    242  },
    243  {
    244    initialHTML:
    245      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    246        `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b>\nghi</div>`,
    247    expectedHTML: aAttrsInLeftBlock => {
    248      return [
    249        `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` +
    250          `<div style="${rightWhiteSpace}">ghi</div>`,
    251        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` +
    252          `<div style="${rightWhiteSpace}">ghi</div>`,
    253      ];
    254    },
    255    skip: !rightWhiteSpacePreserveLineBreaks,
    256  },
    257  {
    258    initialHTML:
    259      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    260        `<div style="${rightWhiteSpace}"><b>${caretInRight}def</b><br>ghi</div>`,
    261    expectedHTML: aAttrsInLeftBlock => {
    262      return [
    263        `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` +
    264          `<div style="${rightWhiteSpace}">ghi</div>`,
    265        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` +
    266          `<div style="${rightWhiteSpace}">ghi</div>`,
    267      ];
    268    },
    269  },
    270  {
    271    initialHTML:
    272      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    273        `<div style="${rightWhiteSpace}"><b>${caretInRight}def\n</b>ghi</div>`,
    274    expectedHTML: aAttrsInLeftBlock => {
    275      return [
    276        `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` +
    277          `<div style="${rightWhiteSpace}">ghi</div>`,
    278        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` +
    279          `<div style="${rightWhiteSpace}">ghi</div>`,
    280      ];
    281    },
    282    skip: !rightWhiteSpacePreserveLineBreaks,
    283  },
    284  {
    285    initialHTML:
    286      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    287        `<div style="${rightWhiteSpace}"><b>${caretInRight}def<br></b>ghi</div>`,
    288    expectedHTML: aAttrsInLeftBlock => {
    289      return [
    290        `<div style="${leftWhiteSpace}">abc<b ${aAttrsInLeftBlock}>def</b></div>` +
    291          `<div style="${rightWhiteSpace}">ghi</div>`,
    292        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}><b>def</b></span></div>` +
    293          `<div style="${rightWhiteSpace}">ghi</div>`,
    294      ];
    295    },
    296  },
    297  // nested paragraph cases
    298  {
    299    initialHTML:
    300      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    301       `<div style="${rightWhiteSpace}"><div>${caretInRight}def</div>ghi</div>`,
    302    expectedHTML: aAttrsInLeftBlock => {
    303      return [
    304        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` +
    305          `<div style="${rightWhiteSpace}">ghi</div>`,
    306      ];
    307    },
    308  },
    309  {
    310    initialHTML:
    311      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    312        `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div></div>`,
    313    expectedHTML: aAttrsInLeftBlock => {
    314      return [
    315        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` +
    316          `<div style="${rightWhiteSpace}"><div>ghi</div></div>`,
    317      ];
    318    },
    319  },
    320  {
    321    initialHTML:
    322      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    323        `<div style="${rightWhiteSpace}"><div>${caretInRight}def</div>ghi\njkl</div>`,
    324    expectedHTML: aAttrsInLeftBlock => {
    325      return [
    326        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` +
    327          `<div style="${rightWhiteSpace}">ghi\njkl</div>`,
    328      ];
    329    },
    330    skip: !rightWhiteSpacePreserveLineBreaks,
    331  },
    332  {
    333    initialHTML:
    334      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    335        `<div style="${rightWhiteSpace}"><div>${caretInRight}def</div>ghi<br>jkl</div>`,
    336    expectedHTML: aAttrsInLeftBlock => {
    337      return [
    338        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` +
    339          `<div style="${rightWhiteSpace}">ghi<br>jkl</div>`,
    340      ];
    341    },
    342  },
    343  {
    344    initialHTML:
    345      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    346        `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div>jkl\nmno</div>`,
    347    expectedHTML: aAttrsInLeftBlock => {
    348      return [
    349        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` +
    350          `<div style="${rightWhiteSpace}"><div>ghi</div>jkl\nmno</div>`,
    351      ];
    352    },
    353    skip: !rightWhiteSpacePreserveLineBreaks,
    354  },
    355  {
    356    initialHTML:
    357      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    358        `<div style="${rightWhiteSpace}">${caretInRight}def<div>ghi</div>jkl<br>mno</div>`,
    359    expectedHTML: aAttrsInLeftBlock => {
    360      return [
    361        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` +
    362          `<div style="${rightWhiteSpace}"><div>ghi</div>jkl<br>mno</div>`,
    363      ];
    364    },
    365  },
    366  {
    367    initialHTML:
    368      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    369        `<div style="${rightWhiteSpace}"><div>${caretInRight}def\nghi</div>jkl</div>`,
    370    expectedHTML: aAttrsInLeftBlock => {
    371      return [
    372        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` +
    373          `<div style="${rightWhiteSpace}"><div>ghi</div>jkl</div>`,
    374      ];
    375    },
    376    skip: !rightWhiteSpacePreserveLineBreaks,
    377  },
    378  {
    379    initialHTML:
    380      `<div style="${leftWhiteSpace}">abc${caretInLeft}</div>` +
    381        `<div style="${rightWhiteSpace}"><div>${caretInRight}def<br>ghi</div>jkl</div>`,
    382    expectedHTML: aAttrsInLeftBlock => {
    383      return [
    384        `<div style="${leftWhiteSpace}">abc<span ${aAttrsInLeftBlock}>def</span></div>` +
    385          `<div style="${rightWhiteSpace}"><div>ghi</div>jkl</div>`,
    386      ];
    387    },
    388  },
    389 ];
    390 
    391 const betweenDivs = /<\/div><div /;
    392 const rightStyleAttr = new RegExp(`style="${rightWhiteSpace}"`, "g");
    393 const leftStyleAttr = new RegExp(`style="${leftWhiteSpace}"`, "g");
    394 const styledRightDiv = new RegExp(`<div style="${rightWhiteSpace}">`, "g");
    395 const styledLeftDiv = new RegExp(`<div style="${leftWhiteSpace}">`, "g");
    396 for (const t of tests) {
    397  if (t.skip) {
    398    continue;
    399  }
    400  promise_test(async () => {
    401    utils.setupEditingHost(t.initialHTML);
    402    await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey());
    403    utils.normalizeStyleAttributeValues();
    404    assert_in_array(
    405      editingHost.innerHTML,
    406      t.expectedHTML(`style="${rightWhiteSpace}"`),
    407      "white-space should be preserved by <span> elements"
    408    );
    409  }, `${commandName} at ${t.initialHTML.replace(/\n/g, "\\n")}`);
    410 
    411  // Repeat same tests with inserting a line break between the paragraphs.
    412  const initialHTMLWithLineBreak =
    413    t.initialHTML.replace(betweenDivs, "</div>\n<div ");
    414  promise_test(async () => {
    415    utils.setupEditingHost(initialHTMLWithLineBreak);
    416    await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey());
    417    utils.normalizeStyleAttributeValues();
    418    assert_in_array(
    419      editingHost.innerHTML,
    420      t.expectedHTML(`style="${rightWhiteSpace}"`),
    421      "white-space should be preserved by <span> elements (testing with a line break between paragraphs)"
    422    );
    423  }, `${commandName} at ${initialHTMLWithLineBreak.replace(/\n/g, "\\n")}`);
    424 
    425  if (rightWhiteSpaceClass !== null) {
    426    // Replace style attribute with class attribute.
    427    const initialHTMLWithClass =
    428      t.initialHTML.replace(
    429        rightStyleAttr,
    430        `class="${rightWhiteSpaceClass}"`
    431      );
    432    if (initialHTMLWithClass != t.initialHTML) {
    433      promise_test(async () => {
    434        utils.setupEditingHost(initialHTMLWithClass);
    435        await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey());
    436        utils.normalizeStyleAttributeValues();
    437        const expectedHTMLs = [];
    438        for (const styleAndOrClassAttr of [
    439          `style="${rightWhiteSpace}"`,
    440          `class="${rightWhiteSpaceClass}" style="${rightWhiteSpace}"`,
    441          `style="${rightWhiteSpace}" class="${rightWhiteSpaceClass}"`,
    442        ]) {
    443          for (const origExpectedHTML of t.expectedHTML(styleAndOrClassAttr)) {
    444            expectedHTMLs.push(
    445              origExpectedHTML.replace(
    446                styledRightDiv,
    447                `<div class="${rightWhiteSpaceClass}">`
    448              )
    449            );
    450          }
    451        }
    452        assert_in_array(
    453          editingHost.innerHTML,
    454          expectedHTMLs,
    455          "white-space should be preserved by <span> elements with class or style attribute"
    456        );
    457      }, `${commandName} at ${initialHTMLWithClass.replace(/\n/g, "\\n")}`);
    458    }
    459  }
    460 
    461  if (leftWhiteSpaceClass !== null) {
    462    // Replace style attribute with class attribute.
    463    const initialHTMLWithClass =
    464      t.initialHTML.replace(
    465        leftStyleAttr,
    466        `class="${leftWhiteSpaceClass}"`
    467      );
    468    if (initialHTMLWithClass != t.initialHTML) {
    469      promise_test(async () => {
    470        utils.setupEditingHost(initialHTMLWithClass);
    471        await (testingBackspace ? utils.sendBackspaceKey() : utils.sendDeleteKey());
    472        utils.normalizeStyleAttributeValues();
    473        const expectedHTMLs = [];
    474        for (const styleAndOrClassAttr of [
    475          `style="${rightWhiteSpace}"`,
    476          `class="${rightWhiteSpaceClass}" style="${rightWhiteSpace}"`,
    477          `style="${rightWhiteSpace}" class="${rightWhiteSpaceClass}"`,
    478        ]) {
    479          for (const origExpectedHTML of t.expectedHTML(styleAndOrClassAttr)) {
    480            expectedHTMLs.push(
    481              origExpectedHTML.replace(
    482                leftStyleAttr,
    483                `class="${leftWhiteSpaceClass}"`
    484              )
    485            );
    486          }
    487        }
    488        assert_in_array(
    489          editingHost.innerHTML,
    490          expectedHTMLs,
    491          "white-space should be preserved by <span> elements with class or style attribute"
    492        );
    493      }, `${commandName} at ${initialHTMLWithClass.replace(/\n/g, "\\n")}`);
    494    }
    495  }
    496 }
    497 </script>
    498 </body>
    499 </html>