From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- editor/libeditor/AutoRangeArray.cpp | 1195 ++ editor/libeditor/AutoRangeArray.h | 469 + editor/libeditor/CSSEditUtils.cpp | 1320 +++ editor/libeditor/CSSEditUtils.h | 389 + editor/libeditor/ChangeAttributeTransaction.cpp | 143 + editor/libeditor/ChangeAttributeTransaction.h | 91 + editor/libeditor/ChangeStyleTransaction.cpp | 342 + editor/libeditor/ChangeStyleTransaction.h | 133 + editor/libeditor/CompositionTransaction.cpp | 435 + editor/libeditor/CompositionTransaction.h | 102 + editor/libeditor/DeleteContentTransactionBase.cpp | 24 + editor/libeditor/DeleteContentTransactionBase.h | 46 + .../libeditor/DeleteMultipleRangesTransaction.cpp | 122 + editor/libeditor/DeleteMultipleRangesTransaction.h | 54 + editor/libeditor/DeleteNodeTransaction.cpp | 167 + editor/libeditor/DeleteNodeTransaction.h | 77 + editor/libeditor/DeleteRangeTransaction.cpp | 399 + editor/libeditor/DeleteRangeTransaction.h | 156 + editor/libeditor/DeleteTextTransaction.cpp | 194 + editor/libeditor/DeleteTextTransaction.h | 99 + editor/libeditor/EditAction.h | 862 ++ editor/libeditor/EditAggregateTransaction.cpp | 124 + editor/libeditor/EditAggregateTransaction.h | 57 + editor/libeditor/EditTransactionBase.cpp | 97 + editor/libeditor/EditTransactionBase.h | 86 + editor/libeditor/EditorBase.cpp | 7065 +++++++++++ editor/libeditor/EditorBase.h | 2963 +++++ editor/libeditor/EditorCommands.cpp | 981 ++ editor/libeditor/EditorCommands.h | 906 ++ editor/libeditor/EditorController.cpp | 140 + editor/libeditor/EditorController.h | 30 + editor/libeditor/EditorDOMPoint.h | 1586 +++ editor/libeditor/EditorEventListener.cpp | 1187 ++ editor/libeditor/EditorEventListener.h | 128 + editor/libeditor/EditorForwards.h | 169 + editor/libeditor/EditorUtils.cpp | 474 + editor/libeditor/EditorUtils.h | 483 + editor/libeditor/HTMLAbsPositionEditor.cpp | 993 ++ editor/libeditor/HTMLAnonymousNodeEditor.cpp | 611 + editor/libeditor/HTMLEditHelpers.cpp | 176 + editor/libeditor/HTMLEditHelpers.h | 1209 ++ editor/libeditor/HTMLEditSubActionHandler.cpp | 11794 +++++++++++++++++++ editor/libeditor/HTMLEditUtils.cpp | 2514 ++++ editor/libeditor/HTMLEditUtils.h | 2559 ++++ editor/libeditor/HTMLEditor.cpp | 7199 +++++++++++ editor/libeditor/HTMLEditor.h | 4696 ++++++++ editor/libeditor/HTMLEditorCommands.cpp | 1302 ++ editor/libeditor/HTMLEditorController.cpp | 142 + editor/libeditor/HTMLEditorController.h | 26 + editor/libeditor/HTMLEditorDataTransfer.cpp | 4325 +++++++ editor/libeditor/HTMLEditorDeleteHandler.cpp | 6854 +++++++++++ editor/libeditor/HTMLEditorDocumentCommands.cpp | 482 + editor/libeditor/HTMLEditorEventListener.cpp | 442 + editor/libeditor/HTMLEditorEventListener.h | 100 + editor/libeditor/HTMLEditorInlines.h | 144 + editor/libeditor/HTMLEditorNestedClasses.h | 522 + editor/libeditor/HTMLEditorObjectResizer.cpp | 1495 +++ editor/libeditor/HTMLEditorState.cpp | 656 ++ editor/libeditor/HTMLInlineTableEditor.cpp | 493 + editor/libeditor/HTMLStyleEditor.cpp | 4430 +++++++ editor/libeditor/HTMLTableEditor.cpp | 4600 ++++++++ editor/libeditor/InsertNodeTransaction.cpp | 184 + editor/libeditor/InsertNodeTransaction.h | 91 + editor/libeditor/InsertTextTransaction.cpp | 182 + editor/libeditor/InsertTextTransaction.h | 93 + editor/libeditor/InternetCiter.cpp | 293 + editor/libeditor/InternetCiter.h | 28 + editor/libeditor/JoinNodesTransaction.cpp | 212 + editor/libeditor/JoinNodesTransaction.h | 112 + editor/libeditor/JoinSplitNodeDirection.h | 51 + editor/libeditor/ManualNAC.h | 118 + editor/libeditor/MoveNodeTransaction.cpp | 300 + editor/libeditor/MoveNodeTransaction.h | 119 + editor/libeditor/PendingStyles.cpp | 503 + editor/libeditor/PendingStyles.h | 339 + editor/libeditor/PlaceholderTransaction.cpp | 351 + editor/libeditor/PlaceholderTransaction.h | 100 + editor/libeditor/ReplaceTextTransaction.cpp | 186 + editor/libeditor/ReplaceTextTransaction.h | 95 + editor/libeditor/SelectionState.cpp | 621 + editor/libeditor/SelectionState.h | 591 + editor/libeditor/SplitNodeTransaction.cpp | 241 + editor/libeditor/SplitNodeTransaction.h | 97 + editor/libeditor/TextEditSubActionHandler.cpp | 817 ++ editor/libeditor/TextEditor.cpp | 1140 ++ editor/libeditor/TextEditor.h | 614 + editor/libeditor/TextEditorDataTransfer.cpp | 273 + editor/libeditor/WSRunObject.cpp | 4390 +++++++ editor/libeditor/WSRunObject.h | 1633 +++ editor/libeditor/crashtests/1057677.html | 9 + editor/libeditor/crashtests/1128787.html | 17 + editor/libeditor/crashtests/1134545.html | 26 + editor/libeditor/crashtests/1158452.html | 10 + editor/libeditor/crashtests/1158651.html | 18 + editor/libeditor/crashtests/1244894.xhtml | 21 + editor/libeditor/crashtests/1264921.html | 1 + editor/libeditor/crashtests/1272490.html | 20 + editor/libeditor/crashtests/1274050.html | 17 + editor/libeditor/crashtests/1317704.html | 42 + editor/libeditor/crashtests/1317718.html | 14 + editor/libeditor/crashtests/1324505.html | 24 + editor/libeditor/crashtests/1343918.html | 21 + editor/libeditor/crashtests/1344097.html | 20 + editor/libeditor/crashtests/1345015.html | 28 + editor/libeditor/crashtests/1348851.html | 19 + editor/libeditor/crashtests/1350772.html | 16 + editor/libeditor/crashtests/1364133.html | 42 + editor/libeditor/crashtests/1366176.html | 30 + editor/libeditor/crashtests/1375131.html | 33 + editor/libeditor/crashtests/1381541.html | 20 + editor/libeditor/crashtests/1383747.html | 15 + editor/libeditor/crashtests/1383755.html | 26 + editor/libeditor/crashtests/1383763.html | 17 + editor/libeditor/crashtests/1384161.html | 17 + editor/libeditor/crashtests/1388075.html | 60 + editor/libeditor/crashtests/1393171.html | 10 + editor/libeditor/crashtests/1402196.html | 29 + editor/libeditor/crashtests/1402469.html | 22 + editor/libeditor/crashtests/1402526.html | 24 + editor/libeditor/crashtests/1402904.html | 38 + editor/libeditor/crashtests/1405747.html | 40 + editor/libeditor/crashtests/1405897.html | 23 + editor/libeditor/crashtests/1408170.html | 40 + editor/libeditor/crashtests/1414581.html | 31 + editor/libeditor/crashtests/1415231.html | 26 + editor/libeditor/crashtests/1423767.html | 17 + editor/libeditor/crashtests/1423776.html | 25 + editor/libeditor/crashtests/1424450.html | 51 + editor/libeditor/crashtests/1425091.html | 25 + editor/libeditor/crashtests/1426709.html | 27 + editor/libeditor/crashtests/1429523.html | 18 + editor/libeditor/crashtests/1429523.xhtml | 18 + editor/libeditor/crashtests/1441619.html | 12 + editor/libeditor/crashtests/1443664.html | 15 + editor/libeditor/crashtests/1444630.html | 29 + editor/libeditor/crashtests/1446451.html | 13 + editor/libeditor/crashtests/1464251.html | 25 + editor/libeditor/crashtests/1470926.html | 9 + editor/libeditor/crashtests/1474978.html | 21 + editor/libeditor/crashtests/1517028.html | 23 + editor/libeditor/crashtests/1525481.html | 23 + editor/libeditor/crashtests/1533913.html | 19 + editor/libeditor/crashtests/1534394.html | 29 + editor/libeditor/crashtests/1547897.html | 25 + editor/libeditor/crashtests/1547898.html | 16 + editor/libeditor/crashtests/1556799.html | 18 + editor/libeditor/crashtests/1574544.html | 17 + editor/libeditor/crashtests/1578916.html | 28 + editor/libeditor/crashtests/1579934.html | 39 + editor/libeditor/crashtests/1581246.html | 21 + editor/libeditor/crashtests/1596516.html | 18 + editor/libeditor/crashtests/1605741.html | 14 + editor/libeditor/crashtests/1613521.html | 16 + editor/libeditor/crashtests/1618906.html | 17 + editor/libeditor/crashtests/1623166.html | 21 + editor/libeditor/crashtests/1623913.html | 30 + editor/libeditor/crashtests/1624005.html | 14 + editor/libeditor/crashtests/1624007.html | 19 + editor/libeditor/crashtests/1624011.html | 12 + editor/libeditor/crashtests/1626002.html | 27 + editor/libeditor/crashtests/1636541.html | 14 + editor/libeditor/crashtests/1644903.html | 19 + editor/libeditor/crashtests/1645983-1.html | 11 + editor/libeditor/crashtests/1645983-2.html | 14 + editor/libeditor/crashtests/1648564.html | 29 + editor/libeditor/crashtests/1655508.html | 34 + editor/libeditor/crashtests/1655539.html | 15 + editor/libeditor/crashtests/1655988.html | 29 + editor/libeditor/crashtests/1659717.html | 14 + editor/libeditor/crashtests/1663725.html | 18 + editor/libeditor/crashtests/1666556.html | 28 + editor/libeditor/crashtests/1677566.html | 31 + editor/libeditor/crashtests/1691051.html | 15 + editor/libeditor/crashtests/1699866.html | 22 + editor/libeditor/crashtests/1701348.html | 10 + editor/libeditor/crashtests/1707630.html | 16 + editor/libeditor/crashtests/336081-1.xhtml | 52 + editor/libeditor/crashtests/403965-1.xhtml | 7 + editor/libeditor/crashtests/428489-1.html | 8 + editor/libeditor/crashtests/429586-1.html | 8 + editor/libeditor/crashtests/431086-1.xhtml | 22 + editor/libeditor/crashtests/475132-1.xhtml | 21 + editor/libeditor/crashtests/503709-1.xhtml | 11 + editor/libeditor/crashtests/513375-1.xhtml | 19 + editor/libeditor/crashtests/535632-1.xhtml | 1 + editor/libeditor/crashtests/574558-1.xhtml | 15 + editor/libeditor/crashtests/580151-1.xhtml | 26 + editor/libeditor/crashtests/582138-1.xhtml | 10 + editor/libeditor/crashtests/633709.xhtml | 68 + editor/libeditor/crashtests/639736-1.xhtml | 19 + editor/libeditor/crashtests/713427-2.xhtml | 28 + editor/libeditor/crashtests/766360.html | 18 + editor/libeditor/crashtests/766387.html | 21 + editor/libeditor/crashtests/766413.html | 42 + editor/libeditor/crashtests/766795.html | 21 + editor/libeditor/crashtests/766845.xhtml | 27 + editor/libeditor/crashtests/767169.html | 23 + editor/libeditor/crashtests/768748.html | 16 + editor/libeditor/crashtests/768765.html | 36 + editor/libeditor/crashtests/769008-1.html | 23 + editor/libeditor/crashtests/769967.xhtml | 16 + editor/libeditor/crashtests/771749.html | 21 + editor/libeditor/crashtests/772282.html | 27 + editor/libeditor/crashtests/776323.html | 18 + editor/libeditor/crashtests/793866.html | 21 + editor/libeditor/crashtests/848644.html | 2 + editor/libeditor/crashtests/crashtests.list | 117 + editor/libeditor/moz.build | 98 + editor/libeditor/tests/.eslintrc.js | 9 + editor/libeditor/tests/browser.ini | 8 + editor/libeditor/tests/browser_bug527935.js | 78 + .../tests/browser_content_command_insert_text.js | 271 + .../tests/browserscope/lib/richtext/LICENSE | 202 + .../tests/browserscope/lib/richtext/README | 58 + .../tests/browserscope/lib/richtext/README.Mozilla | 17 + .../browserscope/lib/richtext/currentStatus.js | 43 + .../browserscope/lib/richtext/current_revision | 1 + .../lib/richtext/richtext/editable.html | 11 + .../lib/richtext/richtext/richtext.html | 1081 ++ .../browserscope/lib/richtext/update_from_upstream | 16 + .../tests/browserscope/lib/richtext2/LICENSE | 202 + .../tests/browserscope/lib/richtext2/README | 58 + .../browserscope/lib/richtext2/README.Mozilla | 27 + .../browserscope/lib/richtext2/currentStatus.js | 1867 +++ .../browserscope/lib/richtext2/current_revision | 1 + .../browserscope/lib/richtext2/platformFailures.js | 28 + .../lib/richtext2/richtext2/__init__.py | 0 .../browserscope/lib/richtext2/richtext2/common.py | 25 + .../lib/richtext2/richtext2/handlers.py | 107 + .../lib/richtext2/richtext2/static/common.css | 116 + .../richtext2/richtext2/static/editable-body.html | 11 + .../richtext2/richtext2/static/editable-dM.html | 17 + .../richtext2/richtext2/static/editable-div.html | 11 + .../lib/richtext2/richtext2/static/editable.css | 66 + .../richtext2/richtext2/static/js/canonicalize.js | 436 + .../lib/richtext2/richtext2/static/js/compare.js | 489 + .../lib/richtext2/richtext2/static/js/output.js | 456 + .../lib/richtext2/richtext2/static/js/pad.js | 269 + .../richtext2/static/js/range-bootstrap.js | 5 + .../lib/richtext2/richtext2/static/js/range.js | 6184 ++++++++++ .../lib/richtext2/richtext2/static/js/run.js | 383 + .../lib/richtext2/richtext2/static/js/units.js | 416 + .../lib/richtext2/richtext2/static/js/variables.js | 227 + .../lib/richtext2/richtext2/templates/output.html | 138 + .../richtext2/richtext2/templates/richtext2.html | 107 + .../lib/richtext2/richtext2/tests/__init__.py | 17 + .../lib/richtext2/richtext2/tests/apply.py | 364 + .../lib/richtext2/richtext2/tests/applyCSS.py | 244 + .../lib/richtext2/richtext2/tests/change.py | 273 + .../lib/richtext2/richtext2/tests/changeCSS.py | 210 + .../lib/richtext2/richtext2/tests/delete.py | 330 + .../lib/richtext2/richtext2/tests/forwarddelete.py | 315 + .../lib/richtext2/richtext2/tests/insert.py | 285 + .../lib/richtext2/richtext2/tests/queryEnabled.py | 215 + .../lib/richtext2/richtext2/tests/queryIndeterm.py | 214 + .../lib/richtext2/richtext2/tests/queryState.py | 575 + .../richtext2/richtext2/tests/querySupported.py | 226 + .../lib/richtext2/richtext2/tests/queryValue.py | 429 + .../lib/richtext2/richtext2/tests/selection.py | 801 ++ .../lib/richtext2/richtext2/tests/unapply.py | 462 + .../lib/richtext2/richtext2/tests/unapplyCSS.py | 226 + .../lib/richtext2/richtext2/unittestexample.html | 103 + .../lib/richtext2/update_from_upstream | 19 + editor/libeditor/tests/browserscope/mochitest.ini | 59 + .../tests/browserscope/test_richtext.html | 48 + .../tests/browserscope/test_richtext2.html | 238 + editor/libeditor/tests/bug527935.html | 11 + editor/libeditor/tests/bug527935_2.html | 1 + editor/libeditor/tests/chrome.ini | 20 + editor/libeditor/tests/data/cfhtml-chromium.txt | Bin 0 -> 856 bytes editor/libeditor/tests/data/cfhtml-firefox.txt | Bin 0 -> 266 bytes editor/libeditor/tests/data/cfhtml-ie.txt | Bin 0 -> 1080 bytes editor/libeditor/tests/data/cfhtml-nocontext.txt | 18 + editor/libeditor/tests/data/cfhtml-ooo.txt | Bin 0 -> 649 bytes editor/libeditor/tests/file_bug289384-1.html | 1 + editor/libeditor/tests/file_bug289384-2.html | 1 + editor/libeditor/tests/file_bug549262.html | 8 + editor/libeditor/tests/file_bug586662.html | 7 + editor/libeditor/tests/file_bug611182.html | 1 + editor/libeditor/tests/file_bug611182.sjs | 254 + editor/libeditor/tests/file_bug635636.xhtml | 3 + editor/libeditor/tests/file_bug635636_2.html | 1 + editor/libeditor/tests/file_bug674770-1.html | 5 + editor/libeditor/tests/file_bug795418-2.sjs | 10 + editor/libeditor/tests/file_bug915962.html | 13 + editor/libeditor/tests/file_bug966155.html | 1 + editor/libeditor/tests/file_bug966552.html | 1 + editor/libeditor/tests/file_sanitizer_on_paste.sjs | 19 + .../tests/file_select_all_without_body.html | 38 + editor/libeditor/tests/green.png | Bin 0 -> 334 bytes editor/libeditor/tests/mochitest.ini | 353 + editor/libeditor/tests/test_CF_HTML_clipboard.html | 149 + .../tests/test_abs_positioner_appearance.html | 177 + ...test_abs_positioner_hidden_during_dragging.html | 102 + .../test_abs_positioner_positioning_elements.html | 196 + editor/libeditor/tests/test_backspace_vs.html | 128 + editor/libeditor/tests/test_bug1026397.html | 101 + editor/libeditor/tests/test_bug1053048.html | 71 + editor/libeditor/tests/test_bug1068979.html | 72 + editor/libeditor/tests/test_bug1094000.html | 147 + editor/libeditor/tests/test_bug1102906.html | 51 + editor/libeditor/tests/test_bug1109465.html | 65 + editor/libeditor/tests/test_bug1130651.html | 17 + editor/libeditor/tests/test_bug1140105.html | 64 + editor/libeditor/tests/test_bug1140617.html | 37 + editor/libeditor/tests/test_bug1151186.html | 69 + editor/libeditor/tests/test_bug1153237.html | 48 + editor/libeditor/tests/test_bug1162952.html | 43 + editor/libeditor/tests/test_bug1181130-1.html | 50 + editor/libeditor/tests/test_bug1181130-2.html | 44 + editor/libeditor/tests/test_bug1186799.html | 78 + editor/libeditor/tests/test_bug1230473.html | 103 + editor/libeditor/tests/test_bug1247483.html | 61 + editor/libeditor/tests/test_bug1248128.html | 52 + editor/libeditor/tests/test_bug1248185.html | 56 + editor/libeditor/tests/test_bug1250010.html | 87 + editor/libeditor/tests/test_bug1257363.html | 180 + editor/libeditor/tests/test_bug1258085.html | 66 + editor/libeditor/tests/test_bug1268736.html | 62 + editor/libeditor/tests/test_bug1270235.html | 46 + editor/libeditor/tests/test_bug1306532.html | 68 + editor/libeditor/tests/test_bug1310912.html | 242 + editor/libeditor/tests/test_bug1314790.html | 57 + editor/libeditor/tests/test_bug1315065.html | 145 + editor/libeditor/tests/test_bug1316302.html | 50 + editor/libeditor/tests/test_bug1328023.html | 61 + editor/libeditor/tests/test_bug1330796.html | 95 + editor/libeditor/tests/test_bug1332876.html | 57 + editor/libeditor/tests/test_bug1352799.html | 84 + editor/libeditor/tests/test_bug1355792.html | 17 + editor/libeditor/tests/test_bug1358025.html | 98 + editor/libeditor/tests/test_bug1361008.html | 61 + editor/libeditor/tests/test_bug1361052.html | 50 + editor/libeditor/tests/test_bug1385905.html | 51 + editor/libeditor/tests/test_bug1390562.html | 67 + editor/libeditor/tests/test_bug1394758.html | 60 + editor/libeditor/tests/test_bug1397412.xhtml | 65 + editor/libeditor/tests/test_bug1399722.html | 38 + editor/libeditor/tests/test_bug1406726.html | 126 + editor/libeditor/tests/test_bug1409520.html | 45 + editor/libeditor/tests/test_bug1425997.html | 63 + editor/libeditor/tests/test_bug1543312.html | 70 + editor/libeditor/tests/test_bug1568996.html | 67 + editor/libeditor/tests/test_bug1574596.html | 64 + editor/libeditor/tests/test_bug1581337.html | 33 + editor/libeditor/tests/test_bug1619852.html | 34 + editor/libeditor/tests/test_bug1620778.html | 27 + editor/libeditor/tests/test_bug1649005.html | 49 + editor/libeditor/tests/test_bug1659276.html | 78 + editor/libeditor/tests/test_bug1704381.html | 48 + editor/libeditor/tests/test_bug200416.html | 15 + editor/libeditor/tests/test_bug289384.html | 48 + editor/libeditor/tests/test_bug290026.html | 52 + editor/libeditor/tests/test_bug291780.html | 49 + editor/libeditor/tests/test_bug309731.html | 58 + editor/libeditor/tests/test_bug316447.html | 16 + editor/libeditor/tests/test_bug318065.html | 82 + editor/libeditor/tests/test_bug332636.html | 75 + .../libeditor/tests/test_bug332636.html^headers^ | 1 + editor/libeditor/tests/test_bug358033.html | 41 + editor/libeditor/tests/test_bug372345.html | 58 + editor/libeditor/tests/test_bug404320.html | 87 + editor/libeditor/tests/test_bug408231.html | 233 + editor/libeditor/tests/test_bug410986.html | 80 + editor/libeditor/tests/test_bug414526.html | 234 + editor/libeditor/tests/test_bug417418.html | 78 + editor/libeditor/tests/test_bug426246.html | 71 + editor/libeditor/tests/test_bug430392.html | 171 + editor/libeditor/tests/test_bug439808.html | 37 + editor/libeditor/tests/test_bug442186.html | 103 + editor/libeditor/tests/test_bug455992.html | 102 + editor/libeditor/tests/test_bug456244.html | 69 + editor/libeditor/tests/test_bug460740.html | 124 + editor/libeditor/tests/test_bug46555.html | 47 + editor/libeditor/tests/test_bug471319.html | 77 + editor/libeditor/tests/test_bug471722.html | 74 + editor/libeditor/tests/test_bug478725.html | 130 + editor/libeditor/tests/test_bug480647.html | 110 + editor/libeditor/tests/test_bug480972.html | 97 + editor/libeditor/tests/test_bug483651.html | 52 + editor/libeditor/tests/test_bug489202.xhtml | 73 + editor/libeditor/tests/test_bug490879.html | 54 + editor/libeditor/tests/test_bug502673.html | 97 + editor/libeditor/tests/test_bug514156.html | 46 + editor/libeditor/tests/test_bug520189.html | 620 + editor/libeditor/tests/test_bug525389.html | 207 + editor/libeditor/tests/test_bug537046.html | 49 + editor/libeditor/tests/test_bug549262.html | 160 + editor/libeditor/tests/test_bug550434.html | 42 + editor/libeditor/tests/test_bug551704.html | 126 + editor/libeditor/tests/test_bug552782.html | 46 + editor/libeditor/tests/test_bug567213.html | 58 + editor/libeditor/tests/test_bug569988.html | 103 + editor/libeditor/tests/test_bug570144.html | 123 + editor/libeditor/tests/test_bug578771.html | 63 + editor/libeditor/tests/test_bug586662.html | 62 + editor/libeditor/tests/test_bug590554.html | 36 + editor/libeditor/tests/test_bug592592.html | 72 + editor/libeditor/tests/test_bug596001.html | 57 + editor/libeditor/tests/test_bug596506.html | 55 + editor/libeditor/tests/test_bug597331.html | 73 + editor/libeditor/tests/test_bug597784.html | 37 + editor/libeditor/tests/test_bug599322.html | 58 + editor/libeditor/tests/test_bug599983.html | 16 + editor/libeditor/tests/test_bug599983.xhtml | 67 + editor/libeditor/tests/test_bug600570.html | 81 + editor/libeditor/tests/test_bug603556.html | 53 + editor/libeditor/tests/test_bug604532.html | 42 + editor/libeditor/tests/test_bug607584.html | 41 + editor/libeditor/tests/test_bug607584.xhtml | 112 + editor/libeditor/tests/test_bug611182.html | 105 + editor/libeditor/tests/test_bug612128.html | 42 + editor/libeditor/tests/test_bug612447.html | 74 + editor/libeditor/tests/test_bug616590.xhtml | 101 + editor/libeditor/tests/test_bug620906.html | 50 + editor/libeditor/tests/test_bug622371.html | 44 + editor/libeditor/tests/test_bug625452.html | 66 + editor/libeditor/tests/test_bug629172.html | 105 + editor/libeditor/tests/test_bug629845.html | 58 + editor/libeditor/tests/test_bug635636.html | 63 + editor/libeditor/tests/test_bug638596.html | 34 + editor/libeditor/tests/test_bug641466.html | 48 + editor/libeditor/tests/test_bug645914.html | 63 + editor/libeditor/tests/test_bug646194.html | 36 + editor/libeditor/tests/test_bug668599.html | 73 + editor/libeditor/tests/test_bug674770-1.html | 85 + editor/libeditor/tests/test_bug674770-2.html | 374 + editor/libeditor/tests/test_bug674861.html | 194 + editor/libeditor/tests/test_bug676401.html | 129 + editor/libeditor/tests/test_bug677752.html | 107 + editor/libeditor/tests/test_bug681229.html | 50 + editor/libeditor/tests/test_bug686203.html | 50 + editor/libeditor/tests/test_bug692520.html | 41 + editor/libeditor/tests/test_bug697842.html | 114 + editor/libeditor/tests/test_bug725069.html | 34 + editor/libeditor/tests/test_bug735059.html | 22 + editor/libeditor/tests/test_bug738366.html | 24 + editor/libeditor/tests/test_bug740784.html | 46 + editor/libeditor/tests/test_bug742261.html | 14 + editor/libeditor/tests/test_bug757371.html | 26 + editor/libeditor/tests/test_bug757771.html | 31 + editor/libeditor/tests/test_bug772796.html | 487 + editor/libeditor/tests/test_bug773262.html | 63 + editor/libeditor/tests/test_bug780035.html | 23 + editor/libeditor/tests/test_bug780908.xhtml | 110 + editor/libeditor/tests/test_bug787432.html | 17 + editor/libeditor/tests/test_bug790475.html | 90 + editor/libeditor/tests/test_bug795418-2.html | 87 + editor/libeditor/tests/test_bug795418-3.html | 89 + editor/libeditor/tests/test_bug795418-4.html | 70 + editor/libeditor/tests/test_bug795418-5.html | 69 + editor/libeditor/tests/test_bug795418-6.html | 69 + editor/libeditor/tests/test_bug795418.html | 70 + editor/libeditor/tests/test_bug795785.html | 139 + editor/libeditor/tests/test_bug796839.html | 17 + editor/libeditor/tests/test_bug830600.html | 97 + editor/libeditor/tests/test_bug832025.html | 43 + editor/libeditor/tests/test_bug850043.html | 59 + editor/libeditor/tests/test_bug857487.html | 68 + editor/libeditor/tests/test_bug858918.html | 16 + editor/libeditor/tests/test_bug915962.html | 120 + editor/libeditor/tests/test_bug966155.html | 54 + editor/libeditor/tests/test_bug966552.html | 42 + editor/libeditor/tests/test_bug974309.html | 74 + editor/libeditor/tests/test_bug998188.html | 51 + .../tests/test_can_undo_after_setting_value.xhtml | 38 + ...st_cannot_undo_after_reinitializing_editor.html | 50 + .../tests/test_caret_move_in_vertical_content.html | 209 + editor/libeditor/tests/test_cmd_absPos.html | 296 + .../libeditor/tests/test_cmd_backgroundColor.html | 223 + .../tests/test_cmd_fontFace_with_empty_string.html | 30 + .../libeditor/tests/test_cmd_fontFace_with_tt.html | 73 + editor/libeditor/tests/test_cmd_increaseFont.html | 22 + .../libeditor/tests/test_cmd_paragraphState.html | 55 + .../test_composition_event_created_in_chrome.html | 76 + ...t_composition_with_highlight_in_texteditor.html | 62 + .../tests/test_contenteditable_focus.html | 335 + .../test_contenteditable_text_input_handling.html | 315 + .../test_cut_copy_delete_command_enabled.html | 227 + .../test_cut_copy_delete_command_enabled.xhtml | 215 + editor/libeditor/tests/test_cut_copy_password.html | 92 + ...defaultParagraphSeparatorBR_between_blocks.html | 62 + .../tests/test_dom_input_event_on_htmleditor.html | 1694 +++ .../tests/test_dom_input_event_on_texteditor.html | 926 ++ editor/libeditor/tests/test_dragdrop.html | 3451 ++++++ .../tests/test_execCommandPaste_noTarget.html | 45 + ...us_caret_navigation_between_nested_editors.html | 207 + ...focused_document_element_becoming_editable.html | 157 + editor/libeditor/tests/test_handle_new_lines.html | 129 + .../tests/test_htmleditor_keyevent_handling.html | 676 ++ .../tests/test_htmleditor_tab_key_handling.html | 112 + ..._initial_selection_and_caret_of_designMode.html | 57 + .../libeditor/tests/test_inlineTableEditing.html | 45 + .../libeditor/tests/test_inline_style_cache.html | 151 + ...tHTML_starting_with_multiple_comment_nodes.html | 40 + .../tests/test_insertParagraph_in_h2_and_li.html | 172 + ...est_insertParagraph_in_inline_editing_host.html | 67 + ...t_join_split_node_direction_change_command.html | 197 + .../tests/test_keypress_untrusted_event.html | 105 + .../tests/test_label_contenteditable.html | 18 + .../libeditor/tests/test_middle_click_paste.html | 680 ++ ...sIEditorMailSupport_insertAsCitedQuotation.html | 322 + ...EditorMailSupport_insertTextWithQuotations.html | 104 + .../tests/test_nsIEditor_beginningOfDocument.html | 119 + .../tests/test_nsIEditor_canUndo_canRedo.html | 183 + .../tests/test_nsIEditor_clearUndoRedo.html | 125 + .../tests/test_nsIEditor_documentCharacterSet.html | 113 + .../tests/test_nsIEditor_documentIsEmpty.html | 150 + .../tests/test_nsIEditor_insertLineBreak.html | 416 + .../tests/test_nsIEditor_isSelectionEditable.html | 16 + .../tests/test_nsIEditor_outputToString.html | 135 + editor/libeditor/tests/test_nsIEditor_undoAll.html | 115 + .../tests/test_nsIEditor_undoRedoEnabled.html | 91 + ..._nsIHTMLEditor_getElementOrParentByTagName.html | 449 + .../test_nsIHTMLEditor_getParagraphState.html | 156 + .../test_nsIHTMLEditor_getSelectedElement.html | 816 ++ ...est_nsIHTMLEditor_insertElementAtSelection.html | 185 + .../test_nsIHTMLEditor_removeInlineProperty.html | 420 + .../tests/test_nsIHTMLEditor_selectElement.html | 131 + .../test_nsIHTMLEditor_setBackgroundColor.html | 187 + .../test_nsIHTMLObjectResizer_hideResizers.html | 54 + .../tests/test_nsITableEditor_deleteTableCell.html | 716 ++ ...est_nsITableEditor_deleteTableCellContents.html | 296 + .../test_nsITableEditor_deleteTableColumn.html | 515 + .../tests/test_nsITableEditor_deleteTableRow.html | 522 + .../tests/test_nsITableEditor_getCellAt.html | 138 + .../tests/test_nsITableEditor_getCellDataAt.html | 751 ++ .../tests/test_nsITableEditor_getCellIndexes.html | 91 + .../tests/test_nsITableEditor_getFirstRow.html | 105 + ...nsITableEditor_getFirstSelectedCellInTable.html | 201 + .../test_nsITableEditor_getSelectedCells.html | 295 + .../test_nsITableEditor_getSelectedCellsType.html | 251 + ...ableEditor_getSelectedOrParentTableElement.html | 283 + .../tests/test_nsITableEditor_getTableSize.html | 94 + .../tests/test_nsITableEditor_insertTableCell.html | 558 + .../test_nsITableEditor_insertTableColumn.html | 547 + .../tests/test_nsITableEditor_insertTableRow.html | 432 + .../test_password_input_with_unmasked_range.html | 417 + editor/libeditor/tests/test_password_paste.html | 65 + .../tests/test_password_per_word_operation.html | 148 + .../libeditor/tests/test_password_unmask_API.html | 318 + .../tests/test_pasteImgFromTransferable.html | 78 + editor/libeditor/tests/test_pasteImgTextarea.html | 19 + editor/libeditor/tests/test_pasteImgTextarea.xhtml | 26 + .../tests/test_paste_as_quote_in_text_control.html | 48 + .../libeditor/tests/test_paste_no_formatting.html | 218 + ...ste_redirect_focus_in_paste_event_listener.html | 143 + .../tests/test_pasting_in_root_element.xhtml | 74 + ...ng_in_temporarily_created_div_outside_body.html | 42 + .../libeditor/tests/test_pasting_table_rows.html | 554 + .../test_pasting_text_longer_than_maxlength.html | 53 + .../libeditor/tests/test_resizers_appearance.html | 109 + .../tests/test_resizers_resizing_elements.html | 299 + .../tests/test_root_element_replacement.html | 140 + .../libeditor/tests/test_sanitizer_on_paste.html | 48 + .../tests/test_select_all_without_body.html | 26 + .../tests/test_selection_move_commands.html | 225 + ...ue_longer_than_maxlength_with_setUserInput.html | 69 + editor/libeditor/tests/test_spellcheck_pref.html | 22 + .../tests/test_state_change_on_reframe.html | 29 + .../tests/test_textarea_value_not_include_cr.html | 95 + .../tests/test_texteditor_keyevent_handling.html | 349 + .../libeditor/tests/test_texteditor_textnode.html | 52 + .../test_texteditor_tripleclick_setvalue.html | 27 + .../tests/test_texteditor_wrapping_long_line.html | 45 + .../tests/test_typing_at_edge_of_anchor.html | 476 + ...test_undo_after_spellchecker_replaces_word.html | 179 + .../test_undo_redo_stack_after_setting_value.html | 168 + .../libeditor/tests/test_undo_with_editingui.html | 160 + 569 files changed, 157622 insertions(+) create mode 100644 editor/libeditor/AutoRangeArray.cpp create mode 100644 editor/libeditor/AutoRangeArray.h create mode 100644 editor/libeditor/CSSEditUtils.cpp create mode 100644 editor/libeditor/CSSEditUtils.h create mode 100644 editor/libeditor/ChangeAttributeTransaction.cpp create mode 100644 editor/libeditor/ChangeAttributeTransaction.h create mode 100644 editor/libeditor/ChangeStyleTransaction.cpp create mode 100644 editor/libeditor/ChangeStyleTransaction.h create mode 100644 editor/libeditor/CompositionTransaction.cpp create mode 100644 editor/libeditor/CompositionTransaction.h create mode 100644 editor/libeditor/DeleteContentTransactionBase.cpp create mode 100644 editor/libeditor/DeleteContentTransactionBase.h create mode 100644 editor/libeditor/DeleteMultipleRangesTransaction.cpp create mode 100644 editor/libeditor/DeleteMultipleRangesTransaction.h create mode 100644 editor/libeditor/DeleteNodeTransaction.cpp create mode 100644 editor/libeditor/DeleteNodeTransaction.h create mode 100644 editor/libeditor/DeleteRangeTransaction.cpp create mode 100644 editor/libeditor/DeleteRangeTransaction.h create mode 100644 editor/libeditor/DeleteTextTransaction.cpp create mode 100644 editor/libeditor/DeleteTextTransaction.h create mode 100644 editor/libeditor/EditAction.h create mode 100644 editor/libeditor/EditAggregateTransaction.cpp create mode 100644 editor/libeditor/EditAggregateTransaction.h create mode 100644 editor/libeditor/EditTransactionBase.cpp create mode 100644 editor/libeditor/EditTransactionBase.h create mode 100644 editor/libeditor/EditorBase.cpp create mode 100644 editor/libeditor/EditorBase.h create mode 100644 editor/libeditor/EditorCommands.cpp create mode 100644 editor/libeditor/EditorCommands.h create mode 100644 editor/libeditor/EditorController.cpp create mode 100644 editor/libeditor/EditorController.h create mode 100644 editor/libeditor/EditorDOMPoint.h create mode 100644 editor/libeditor/EditorEventListener.cpp create mode 100644 editor/libeditor/EditorEventListener.h create mode 100644 editor/libeditor/EditorForwards.h create mode 100644 editor/libeditor/EditorUtils.cpp create mode 100644 editor/libeditor/EditorUtils.h create mode 100644 editor/libeditor/HTMLAbsPositionEditor.cpp create mode 100644 editor/libeditor/HTMLAnonymousNodeEditor.cpp create mode 100644 editor/libeditor/HTMLEditHelpers.cpp create mode 100644 editor/libeditor/HTMLEditHelpers.h create mode 100644 editor/libeditor/HTMLEditSubActionHandler.cpp create mode 100644 editor/libeditor/HTMLEditUtils.cpp create mode 100644 editor/libeditor/HTMLEditUtils.h create mode 100644 editor/libeditor/HTMLEditor.cpp create mode 100644 editor/libeditor/HTMLEditor.h create mode 100644 editor/libeditor/HTMLEditorCommands.cpp create mode 100644 editor/libeditor/HTMLEditorController.cpp create mode 100644 editor/libeditor/HTMLEditorController.h create mode 100644 editor/libeditor/HTMLEditorDataTransfer.cpp create mode 100644 editor/libeditor/HTMLEditorDeleteHandler.cpp create mode 100644 editor/libeditor/HTMLEditorDocumentCommands.cpp create mode 100644 editor/libeditor/HTMLEditorEventListener.cpp create mode 100644 editor/libeditor/HTMLEditorEventListener.h create mode 100644 editor/libeditor/HTMLEditorInlines.h create mode 100644 editor/libeditor/HTMLEditorNestedClasses.h create mode 100644 editor/libeditor/HTMLEditorObjectResizer.cpp create mode 100644 editor/libeditor/HTMLEditorState.cpp create mode 100644 editor/libeditor/HTMLInlineTableEditor.cpp create mode 100644 editor/libeditor/HTMLStyleEditor.cpp create mode 100644 editor/libeditor/HTMLTableEditor.cpp create mode 100644 editor/libeditor/InsertNodeTransaction.cpp create mode 100644 editor/libeditor/InsertNodeTransaction.h create mode 100644 editor/libeditor/InsertTextTransaction.cpp create mode 100644 editor/libeditor/InsertTextTransaction.h create mode 100644 editor/libeditor/InternetCiter.cpp create mode 100644 editor/libeditor/InternetCiter.h create mode 100644 editor/libeditor/JoinNodesTransaction.cpp create mode 100644 editor/libeditor/JoinNodesTransaction.h create mode 100644 editor/libeditor/JoinSplitNodeDirection.h create mode 100644 editor/libeditor/ManualNAC.h create mode 100644 editor/libeditor/MoveNodeTransaction.cpp create mode 100644 editor/libeditor/MoveNodeTransaction.h create mode 100644 editor/libeditor/PendingStyles.cpp create mode 100644 editor/libeditor/PendingStyles.h create mode 100644 editor/libeditor/PlaceholderTransaction.cpp create mode 100644 editor/libeditor/PlaceholderTransaction.h create mode 100644 editor/libeditor/ReplaceTextTransaction.cpp create mode 100644 editor/libeditor/ReplaceTextTransaction.h create mode 100644 editor/libeditor/SelectionState.cpp create mode 100644 editor/libeditor/SelectionState.h create mode 100644 editor/libeditor/SplitNodeTransaction.cpp create mode 100644 editor/libeditor/SplitNodeTransaction.h create mode 100644 editor/libeditor/TextEditSubActionHandler.cpp create mode 100644 editor/libeditor/TextEditor.cpp create mode 100644 editor/libeditor/TextEditor.h create mode 100644 editor/libeditor/TextEditorDataTransfer.cpp create mode 100644 editor/libeditor/WSRunObject.cpp create mode 100644 editor/libeditor/WSRunObject.h create mode 100644 editor/libeditor/crashtests/1057677.html create mode 100644 editor/libeditor/crashtests/1128787.html create mode 100644 editor/libeditor/crashtests/1134545.html create mode 100644 editor/libeditor/crashtests/1158452.html create mode 100644 editor/libeditor/crashtests/1158651.html create mode 100644 editor/libeditor/crashtests/1244894.xhtml create mode 100644 editor/libeditor/crashtests/1264921.html create mode 100644 editor/libeditor/crashtests/1272490.html create mode 100644 editor/libeditor/crashtests/1274050.html create mode 100644 editor/libeditor/crashtests/1317704.html create mode 100644 editor/libeditor/crashtests/1317718.html create mode 100644 editor/libeditor/crashtests/1324505.html create mode 100644 editor/libeditor/crashtests/1343918.html create mode 100644 editor/libeditor/crashtests/1344097.html create mode 100644 editor/libeditor/crashtests/1345015.html create mode 100644 editor/libeditor/crashtests/1348851.html create mode 100644 editor/libeditor/crashtests/1350772.html create mode 100644 editor/libeditor/crashtests/1364133.html create mode 100644 editor/libeditor/crashtests/1366176.html create mode 100644 editor/libeditor/crashtests/1375131.html create mode 100644 editor/libeditor/crashtests/1381541.html create mode 100644 editor/libeditor/crashtests/1383747.html create mode 100644 editor/libeditor/crashtests/1383755.html create mode 100644 editor/libeditor/crashtests/1383763.html create mode 100644 editor/libeditor/crashtests/1384161.html create mode 100644 editor/libeditor/crashtests/1388075.html create mode 100644 editor/libeditor/crashtests/1393171.html create mode 100644 editor/libeditor/crashtests/1402196.html create mode 100644 editor/libeditor/crashtests/1402469.html create mode 100644 editor/libeditor/crashtests/1402526.html create mode 100644 editor/libeditor/crashtests/1402904.html create mode 100644 editor/libeditor/crashtests/1405747.html create mode 100644 editor/libeditor/crashtests/1405897.html create mode 100644 editor/libeditor/crashtests/1408170.html create mode 100644 editor/libeditor/crashtests/1414581.html create mode 100644 editor/libeditor/crashtests/1415231.html create mode 100644 editor/libeditor/crashtests/1423767.html create mode 100644 editor/libeditor/crashtests/1423776.html create mode 100644 editor/libeditor/crashtests/1424450.html create mode 100644 editor/libeditor/crashtests/1425091.html create mode 100644 editor/libeditor/crashtests/1426709.html create mode 100644 editor/libeditor/crashtests/1429523.html create mode 100644 editor/libeditor/crashtests/1429523.xhtml create mode 100644 editor/libeditor/crashtests/1441619.html create mode 100644 editor/libeditor/crashtests/1443664.html create mode 100644 editor/libeditor/crashtests/1444630.html create mode 100644 editor/libeditor/crashtests/1446451.html create mode 100644 editor/libeditor/crashtests/1464251.html create mode 100644 editor/libeditor/crashtests/1470926.html create mode 100644 editor/libeditor/crashtests/1474978.html create mode 100644 editor/libeditor/crashtests/1517028.html create mode 100644 editor/libeditor/crashtests/1525481.html create mode 100644 editor/libeditor/crashtests/1533913.html create mode 100644 editor/libeditor/crashtests/1534394.html create mode 100644 editor/libeditor/crashtests/1547897.html create mode 100644 editor/libeditor/crashtests/1547898.html create mode 100644 editor/libeditor/crashtests/1556799.html create mode 100644 editor/libeditor/crashtests/1574544.html create mode 100644 editor/libeditor/crashtests/1578916.html create mode 100644 editor/libeditor/crashtests/1579934.html create mode 100644 editor/libeditor/crashtests/1581246.html create mode 100644 editor/libeditor/crashtests/1596516.html create mode 100644 editor/libeditor/crashtests/1605741.html create mode 100644 editor/libeditor/crashtests/1613521.html create mode 100644 editor/libeditor/crashtests/1618906.html create mode 100644 editor/libeditor/crashtests/1623166.html create mode 100644 editor/libeditor/crashtests/1623913.html create mode 100644 editor/libeditor/crashtests/1624005.html create mode 100644 editor/libeditor/crashtests/1624007.html create mode 100644 editor/libeditor/crashtests/1624011.html create mode 100644 editor/libeditor/crashtests/1626002.html create mode 100644 editor/libeditor/crashtests/1636541.html create mode 100644 editor/libeditor/crashtests/1644903.html create mode 100644 editor/libeditor/crashtests/1645983-1.html create mode 100644 editor/libeditor/crashtests/1645983-2.html create mode 100644 editor/libeditor/crashtests/1648564.html create mode 100644 editor/libeditor/crashtests/1655508.html create mode 100644 editor/libeditor/crashtests/1655539.html create mode 100644 editor/libeditor/crashtests/1655988.html create mode 100644 editor/libeditor/crashtests/1659717.html create mode 100644 editor/libeditor/crashtests/1663725.html create mode 100644 editor/libeditor/crashtests/1666556.html create mode 100644 editor/libeditor/crashtests/1677566.html create mode 100644 editor/libeditor/crashtests/1691051.html create mode 100644 editor/libeditor/crashtests/1699866.html create mode 100644 editor/libeditor/crashtests/1701348.html create mode 100644 editor/libeditor/crashtests/1707630.html create mode 100644 editor/libeditor/crashtests/336081-1.xhtml create mode 100644 editor/libeditor/crashtests/403965-1.xhtml create mode 100644 editor/libeditor/crashtests/428489-1.html create mode 100644 editor/libeditor/crashtests/429586-1.html create mode 100644 editor/libeditor/crashtests/431086-1.xhtml create mode 100644 editor/libeditor/crashtests/475132-1.xhtml create mode 100644 editor/libeditor/crashtests/503709-1.xhtml create mode 100644 editor/libeditor/crashtests/513375-1.xhtml create mode 100644 editor/libeditor/crashtests/535632-1.xhtml create mode 100644 editor/libeditor/crashtests/574558-1.xhtml create mode 100644 editor/libeditor/crashtests/580151-1.xhtml create mode 100644 editor/libeditor/crashtests/582138-1.xhtml create mode 100644 editor/libeditor/crashtests/633709.xhtml create mode 100644 editor/libeditor/crashtests/639736-1.xhtml create mode 100644 editor/libeditor/crashtests/713427-2.xhtml create mode 100644 editor/libeditor/crashtests/766360.html create mode 100644 editor/libeditor/crashtests/766387.html create mode 100644 editor/libeditor/crashtests/766413.html create mode 100644 editor/libeditor/crashtests/766795.html create mode 100644 editor/libeditor/crashtests/766845.xhtml create mode 100644 editor/libeditor/crashtests/767169.html create mode 100644 editor/libeditor/crashtests/768748.html create mode 100644 editor/libeditor/crashtests/768765.html create mode 100644 editor/libeditor/crashtests/769008-1.html create mode 100644 editor/libeditor/crashtests/769967.xhtml create mode 100644 editor/libeditor/crashtests/771749.html create mode 100644 editor/libeditor/crashtests/772282.html create mode 100644 editor/libeditor/crashtests/776323.html create mode 100644 editor/libeditor/crashtests/793866.html create mode 100644 editor/libeditor/crashtests/848644.html create mode 100644 editor/libeditor/crashtests/crashtests.list create mode 100644 editor/libeditor/moz.build create mode 100644 editor/libeditor/tests/.eslintrc.js create mode 100644 editor/libeditor/tests/browser.ini create mode 100644 editor/libeditor/tests/browser_bug527935.js create mode 100644 editor/libeditor/tests/browser_content_command_insert_text.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext/LICENSE create mode 100644 editor/libeditor/tests/browserscope/lib/richtext/README create mode 100644 editor/libeditor/tests/browserscope/lib/richtext/README.Mozilla create mode 100644 editor/libeditor/tests/browserscope/lib/richtext/currentStatus.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext/current_revision create mode 100644 editor/libeditor/tests/browserscope/lib/richtext/richtext/editable.html create mode 100644 editor/libeditor/tests/browserscope/lib/richtext/richtext/richtext.html create mode 100644 editor/libeditor/tests/browserscope/lib/richtext/update_from_upstream create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/LICENSE create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/README create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/README.Mozilla create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/currentStatus.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/current_revision create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/platformFailures.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/__init__.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/common.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/handlers.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/common.css create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/editable-body.html create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/editable-dM.html create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/editable-div.html create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/editable.css create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/js/canonicalize.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/js/compare.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/js/output.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/js/pad.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/js/range-bootstrap.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/js/range.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/js/run.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/js/units.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/static/js/variables.js create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/templates/output.html create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/templates/richtext2.html create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/__init__.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/apply.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/applyCSS.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/change.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/changeCSS.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/delete.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/forwarddelete.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/insert.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/queryEnabled.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/queryIndeterm.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/queryState.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/querySupported.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/queryValue.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/selection.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/unapply.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/tests/unapplyCSS.py create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/richtext2/unittestexample.html create mode 100644 editor/libeditor/tests/browserscope/lib/richtext2/update_from_upstream create mode 100644 editor/libeditor/tests/browserscope/mochitest.ini create mode 100644 editor/libeditor/tests/browserscope/test_richtext.html create mode 100644 editor/libeditor/tests/browserscope/test_richtext2.html create mode 100644 editor/libeditor/tests/bug527935.html create mode 100644 editor/libeditor/tests/bug527935_2.html create mode 100644 editor/libeditor/tests/chrome.ini create mode 100644 editor/libeditor/tests/data/cfhtml-chromium.txt create mode 100644 editor/libeditor/tests/data/cfhtml-firefox.txt create mode 100644 editor/libeditor/tests/data/cfhtml-ie.txt create mode 100644 editor/libeditor/tests/data/cfhtml-nocontext.txt create mode 100644 editor/libeditor/tests/data/cfhtml-ooo.txt create mode 100644 editor/libeditor/tests/file_bug289384-1.html create mode 100644 editor/libeditor/tests/file_bug289384-2.html create mode 100644 editor/libeditor/tests/file_bug549262.html create mode 100644 editor/libeditor/tests/file_bug586662.html create mode 100644 editor/libeditor/tests/file_bug611182.html create mode 100644 editor/libeditor/tests/file_bug611182.sjs create mode 100644 editor/libeditor/tests/file_bug635636.xhtml create mode 100644 editor/libeditor/tests/file_bug635636_2.html create mode 100644 editor/libeditor/tests/file_bug674770-1.html create mode 100644 editor/libeditor/tests/file_bug795418-2.sjs create mode 100644 editor/libeditor/tests/file_bug915962.html create mode 100644 editor/libeditor/tests/file_bug966155.html create mode 100644 editor/libeditor/tests/file_bug966552.html create mode 100644 editor/libeditor/tests/file_sanitizer_on_paste.sjs create mode 100644 editor/libeditor/tests/file_select_all_without_body.html create mode 100644 editor/libeditor/tests/green.png create mode 100644 editor/libeditor/tests/mochitest.ini create mode 100644 editor/libeditor/tests/test_CF_HTML_clipboard.html create mode 100644 editor/libeditor/tests/test_abs_positioner_appearance.html create mode 100644 editor/libeditor/tests/test_abs_positioner_hidden_during_dragging.html create mode 100644 editor/libeditor/tests/test_abs_positioner_positioning_elements.html create mode 100644 editor/libeditor/tests/test_backspace_vs.html create mode 100644 editor/libeditor/tests/test_bug1026397.html create mode 100644 editor/libeditor/tests/test_bug1053048.html create mode 100644 editor/libeditor/tests/test_bug1068979.html create mode 100644 editor/libeditor/tests/test_bug1094000.html create mode 100644 editor/libeditor/tests/test_bug1102906.html create mode 100644 editor/libeditor/tests/test_bug1109465.html create mode 100644 editor/libeditor/tests/test_bug1130651.html create mode 100644 editor/libeditor/tests/test_bug1140105.html create mode 100644 editor/libeditor/tests/test_bug1140617.html create mode 100644 editor/libeditor/tests/test_bug1151186.html create mode 100644 editor/libeditor/tests/test_bug1153237.html create mode 100644 editor/libeditor/tests/test_bug1162952.html create mode 100644 editor/libeditor/tests/test_bug1181130-1.html create mode 100644 editor/libeditor/tests/test_bug1181130-2.html create mode 100644 editor/libeditor/tests/test_bug1186799.html create mode 100644 editor/libeditor/tests/test_bug1230473.html create mode 100644 editor/libeditor/tests/test_bug1247483.html create mode 100644 editor/libeditor/tests/test_bug1248128.html create mode 100644 editor/libeditor/tests/test_bug1248185.html create mode 100644 editor/libeditor/tests/test_bug1250010.html create mode 100644 editor/libeditor/tests/test_bug1257363.html create mode 100644 editor/libeditor/tests/test_bug1258085.html create mode 100644 editor/libeditor/tests/test_bug1268736.html create mode 100644 editor/libeditor/tests/test_bug1270235.html create mode 100644 editor/libeditor/tests/test_bug1306532.html create mode 100644 editor/libeditor/tests/test_bug1310912.html create mode 100644 editor/libeditor/tests/test_bug1314790.html create mode 100644 editor/libeditor/tests/test_bug1315065.html create mode 100644 editor/libeditor/tests/test_bug1316302.html create mode 100644 editor/libeditor/tests/test_bug1328023.html create mode 100644 editor/libeditor/tests/test_bug1330796.html create mode 100644 editor/libeditor/tests/test_bug1332876.html create mode 100644 editor/libeditor/tests/test_bug1352799.html create mode 100644 editor/libeditor/tests/test_bug1355792.html create mode 100644 editor/libeditor/tests/test_bug1358025.html create mode 100644 editor/libeditor/tests/test_bug1361008.html create mode 100644 editor/libeditor/tests/test_bug1361052.html create mode 100644 editor/libeditor/tests/test_bug1385905.html create mode 100644 editor/libeditor/tests/test_bug1390562.html create mode 100644 editor/libeditor/tests/test_bug1394758.html create mode 100644 editor/libeditor/tests/test_bug1397412.xhtml create mode 100644 editor/libeditor/tests/test_bug1399722.html create mode 100644 editor/libeditor/tests/test_bug1406726.html create mode 100644 editor/libeditor/tests/test_bug1409520.html create mode 100644 editor/libeditor/tests/test_bug1425997.html create mode 100644 editor/libeditor/tests/test_bug1543312.html create mode 100644 editor/libeditor/tests/test_bug1568996.html create mode 100644 editor/libeditor/tests/test_bug1574596.html create mode 100644 editor/libeditor/tests/test_bug1581337.html create mode 100644 editor/libeditor/tests/test_bug1619852.html create mode 100644 editor/libeditor/tests/test_bug1620778.html create mode 100644 editor/libeditor/tests/test_bug1649005.html create mode 100644 editor/libeditor/tests/test_bug1659276.html create mode 100644 editor/libeditor/tests/test_bug1704381.html create mode 100644 editor/libeditor/tests/test_bug200416.html create mode 100644 editor/libeditor/tests/test_bug289384.html create mode 100644 editor/libeditor/tests/test_bug290026.html create mode 100644 editor/libeditor/tests/test_bug291780.html create mode 100644 editor/libeditor/tests/test_bug309731.html create mode 100644 editor/libeditor/tests/test_bug316447.html create mode 100644 editor/libeditor/tests/test_bug318065.html create mode 100644 editor/libeditor/tests/test_bug332636.html create mode 100644 editor/libeditor/tests/test_bug332636.html^headers^ create mode 100644 editor/libeditor/tests/test_bug358033.html create mode 100644 editor/libeditor/tests/test_bug372345.html create mode 100644 editor/libeditor/tests/test_bug404320.html create mode 100644 editor/libeditor/tests/test_bug408231.html create mode 100644 editor/libeditor/tests/test_bug410986.html create mode 100644 editor/libeditor/tests/test_bug414526.html create mode 100644 editor/libeditor/tests/test_bug417418.html create mode 100644 editor/libeditor/tests/test_bug426246.html create mode 100644 editor/libeditor/tests/test_bug430392.html create mode 100644 editor/libeditor/tests/test_bug439808.html create mode 100644 editor/libeditor/tests/test_bug442186.html create mode 100644 editor/libeditor/tests/test_bug455992.html create mode 100644 editor/libeditor/tests/test_bug456244.html create mode 100644 editor/libeditor/tests/test_bug460740.html create mode 100644 editor/libeditor/tests/test_bug46555.html create mode 100644 editor/libeditor/tests/test_bug471319.html create mode 100644 editor/libeditor/tests/test_bug471722.html create mode 100644 editor/libeditor/tests/test_bug478725.html create mode 100644 editor/libeditor/tests/test_bug480647.html create mode 100644 editor/libeditor/tests/test_bug480972.html create mode 100644 editor/libeditor/tests/test_bug483651.html create mode 100644 editor/libeditor/tests/test_bug489202.xhtml create mode 100644 editor/libeditor/tests/test_bug490879.html create mode 100644 editor/libeditor/tests/test_bug502673.html create mode 100644 editor/libeditor/tests/test_bug514156.html create mode 100644 editor/libeditor/tests/test_bug520189.html create mode 100644 editor/libeditor/tests/test_bug525389.html create mode 100644 editor/libeditor/tests/test_bug537046.html create mode 100644 editor/libeditor/tests/test_bug549262.html create mode 100644 editor/libeditor/tests/test_bug550434.html create mode 100644 editor/libeditor/tests/test_bug551704.html create mode 100644 editor/libeditor/tests/test_bug552782.html create mode 100644 editor/libeditor/tests/test_bug567213.html create mode 100644 editor/libeditor/tests/test_bug569988.html create mode 100644 editor/libeditor/tests/test_bug570144.html create mode 100644 editor/libeditor/tests/test_bug578771.html create mode 100644 editor/libeditor/tests/test_bug586662.html create mode 100644 editor/libeditor/tests/test_bug590554.html create mode 100644 editor/libeditor/tests/test_bug592592.html create mode 100644 editor/libeditor/tests/test_bug596001.html create mode 100644 editor/libeditor/tests/test_bug596506.html create mode 100644 editor/libeditor/tests/test_bug597331.html create mode 100644 editor/libeditor/tests/test_bug597784.html create mode 100644 editor/libeditor/tests/test_bug599322.html create mode 100644 editor/libeditor/tests/test_bug599983.html create mode 100644 editor/libeditor/tests/test_bug599983.xhtml create mode 100644 editor/libeditor/tests/test_bug600570.html create mode 100644 editor/libeditor/tests/test_bug603556.html create mode 100644 editor/libeditor/tests/test_bug604532.html create mode 100644 editor/libeditor/tests/test_bug607584.html create mode 100644 editor/libeditor/tests/test_bug607584.xhtml create mode 100644 editor/libeditor/tests/test_bug611182.html create mode 100644 editor/libeditor/tests/test_bug612128.html create mode 100644 editor/libeditor/tests/test_bug612447.html create mode 100644 editor/libeditor/tests/test_bug616590.xhtml create mode 100644 editor/libeditor/tests/test_bug620906.html create mode 100644 editor/libeditor/tests/test_bug622371.html create mode 100644 editor/libeditor/tests/test_bug625452.html create mode 100644 editor/libeditor/tests/test_bug629172.html create mode 100644 editor/libeditor/tests/test_bug629845.html create mode 100644 editor/libeditor/tests/test_bug635636.html create mode 100644 editor/libeditor/tests/test_bug638596.html create mode 100644 editor/libeditor/tests/test_bug641466.html create mode 100644 editor/libeditor/tests/test_bug645914.html create mode 100644 editor/libeditor/tests/test_bug646194.html create mode 100644 editor/libeditor/tests/test_bug668599.html create mode 100644 editor/libeditor/tests/test_bug674770-1.html create mode 100644 editor/libeditor/tests/test_bug674770-2.html create mode 100644 editor/libeditor/tests/test_bug674861.html create mode 100644 editor/libeditor/tests/test_bug676401.html create mode 100644 editor/libeditor/tests/test_bug677752.html create mode 100644 editor/libeditor/tests/test_bug681229.html create mode 100644 editor/libeditor/tests/test_bug686203.html create mode 100644 editor/libeditor/tests/test_bug692520.html create mode 100644 editor/libeditor/tests/test_bug697842.html create mode 100644 editor/libeditor/tests/test_bug725069.html create mode 100644 editor/libeditor/tests/test_bug735059.html create mode 100644 editor/libeditor/tests/test_bug738366.html create mode 100644 editor/libeditor/tests/test_bug740784.html create mode 100644 editor/libeditor/tests/test_bug742261.html create mode 100644 editor/libeditor/tests/test_bug757371.html create mode 100644 editor/libeditor/tests/test_bug757771.html create mode 100644 editor/libeditor/tests/test_bug772796.html create mode 100644 editor/libeditor/tests/test_bug773262.html create mode 100644 editor/libeditor/tests/test_bug780035.html create mode 100644 editor/libeditor/tests/test_bug780908.xhtml create mode 100644 editor/libeditor/tests/test_bug787432.html create mode 100644 editor/libeditor/tests/test_bug790475.html create mode 100644 editor/libeditor/tests/test_bug795418-2.html create mode 100644 editor/libeditor/tests/test_bug795418-3.html create mode 100644 editor/libeditor/tests/test_bug795418-4.html create mode 100644 editor/libeditor/tests/test_bug795418-5.html create mode 100644 editor/libeditor/tests/test_bug795418-6.html create mode 100644 editor/libeditor/tests/test_bug795418.html create mode 100644 editor/libeditor/tests/test_bug795785.html create mode 100644 editor/libeditor/tests/test_bug796839.html create mode 100644 editor/libeditor/tests/test_bug830600.html create mode 100644 editor/libeditor/tests/test_bug832025.html create mode 100644 editor/libeditor/tests/test_bug850043.html create mode 100644 editor/libeditor/tests/test_bug857487.html create mode 100644 editor/libeditor/tests/test_bug858918.html create mode 100644 editor/libeditor/tests/test_bug915962.html create mode 100644 editor/libeditor/tests/test_bug966155.html create mode 100644 editor/libeditor/tests/test_bug966552.html create mode 100644 editor/libeditor/tests/test_bug974309.html create mode 100644 editor/libeditor/tests/test_bug998188.html create mode 100644 editor/libeditor/tests/test_can_undo_after_setting_value.xhtml create mode 100644 editor/libeditor/tests/test_cannot_undo_after_reinitializing_editor.html create mode 100644 editor/libeditor/tests/test_caret_move_in_vertical_content.html create mode 100644 editor/libeditor/tests/test_cmd_absPos.html create mode 100644 editor/libeditor/tests/test_cmd_backgroundColor.html create mode 100644 editor/libeditor/tests/test_cmd_fontFace_with_empty_string.html create mode 100644 editor/libeditor/tests/test_cmd_fontFace_with_tt.html create mode 100644 editor/libeditor/tests/test_cmd_increaseFont.html create mode 100644 editor/libeditor/tests/test_cmd_paragraphState.html create mode 100644 editor/libeditor/tests/test_composition_event_created_in_chrome.html create mode 100644 editor/libeditor/tests/test_composition_with_highlight_in_texteditor.html create mode 100644 editor/libeditor/tests/test_contenteditable_focus.html create mode 100644 editor/libeditor/tests/test_contenteditable_text_input_handling.html create mode 100644 editor/libeditor/tests/test_cut_copy_delete_command_enabled.html create mode 100644 editor/libeditor/tests/test_cut_copy_delete_command_enabled.xhtml create mode 100644 editor/libeditor/tests/test_cut_copy_password.html create mode 100644 editor/libeditor/tests/test_defaultParagraphSeparatorBR_between_blocks.html create mode 100644 editor/libeditor/tests/test_dom_input_event_on_htmleditor.html create mode 100644 editor/libeditor/tests/test_dom_input_event_on_texteditor.html create mode 100644 editor/libeditor/tests/test_dragdrop.html create mode 100644 editor/libeditor/tests/test_execCommandPaste_noTarget.html create mode 100644 editor/libeditor/tests/test_focus_caret_navigation_between_nested_editors.html create mode 100644 editor/libeditor/tests/test_focused_document_element_becoming_editable.html create mode 100644 editor/libeditor/tests/test_handle_new_lines.html create mode 100644 editor/libeditor/tests/test_htmleditor_keyevent_handling.html create mode 100644 editor/libeditor/tests/test_htmleditor_tab_key_handling.html create mode 100644 editor/libeditor/tests/test_initial_selection_and_caret_of_designMode.html create mode 100644 editor/libeditor/tests/test_inlineTableEditing.html create mode 100644 editor/libeditor/tests/test_inline_style_cache.html create mode 100644 editor/libeditor/tests/test_insertHTML_starting_with_multiple_comment_nodes.html create mode 100644 editor/libeditor/tests/test_insertParagraph_in_h2_and_li.html create mode 100644 editor/libeditor/tests/test_insertParagraph_in_inline_editing_host.html create mode 100644 editor/libeditor/tests/test_join_split_node_direction_change_command.html create mode 100644 editor/libeditor/tests/test_keypress_untrusted_event.html create mode 100644 editor/libeditor/tests/test_label_contenteditable.html create mode 100644 editor/libeditor/tests/test_middle_click_paste.html create mode 100644 editor/libeditor/tests/test_nsIEditorMailSupport_insertAsCitedQuotation.html create mode 100644 editor/libeditor/tests/test_nsIEditorMailSupport_insertTextWithQuotations.html create mode 100644 editor/libeditor/tests/test_nsIEditor_beginningOfDocument.html create mode 100644 editor/libeditor/tests/test_nsIEditor_canUndo_canRedo.html create mode 100644 editor/libeditor/tests/test_nsIEditor_clearUndoRedo.html create mode 100644 editor/libeditor/tests/test_nsIEditor_documentCharacterSet.html create mode 100644 editor/libeditor/tests/test_nsIEditor_documentIsEmpty.html create mode 100644 editor/libeditor/tests/test_nsIEditor_insertLineBreak.html create mode 100644 editor/libeditor/tests/test_nsIEditor_isSelectionEditable.html create mode 100644 editor/libeditor/tests/test_nsIEditor_outputToString.html create mode 100644 editor/libeditor/tests/test_nsIEditor_undoAll.html create mode 100644 editor/libeditor/tests/test_nsIEditor_undoRedoEnabled.html create mode 100644 editor/libeditor/tests/test_nsIHTMLEditor_getElementOrParentByTagName.html create mode 100644 editor/libeditor/tests/test_nsIHTMLEditor_getParagraphState.html create mode 100644 editor/libeditor/tests/test_nsIHTMLEditor_getSelectedElement.html create mode 100644 editor/libeditor/tests/test_nsIHTMLEditor_insertElementAtSelection.html create mode 100644 editor/libeditor/tests/test_nsIHTMLEditor_removeInlineProperty.html create mode 100644 editor/libeditor/tests/test_nsIHTMLEditor_selectElement.html create mode 100644 editor/libeditor/tests/test_nsIHTMLEditor_setBackgroundColor.html create mode 100644 editor/libeditor/tests/test_nsIHTMLObjectResizer_hideResizers.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_deleteTableCell.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_deleteTableCellContents.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_deleteTableColumn.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_deleteTableRow.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_getCellAt.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_getCellDataAt.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_getCellIndexes.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_getFirstRow.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_getFirstSelectedCellInTable.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_getSelectedCells.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_getSelectedCellsType.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_getSelectedOrParentTableElement.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_getTableSize.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_insertTableCell.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_insertTableColumn.html create mode 100644 editor/libeditor/tests/test_nsITableEditor_insertTableRow.html create mode 100644 editor/libeditor/tests/test_password_input_with_unmasked_range.html create mode 100644 editor/libeditor/tests/test_password_paste.html create mode 100644 editor/libeditor/tests/test_password_per_word_operation.html create mode 100644 editor/libeditor/tests/test_password_unmask_API.html create mode 100644 editor/libeditor/tests/test_pasteImgFromTransferable.html create mode 100644 editor/libeditor/tests/test_pasteImgTextarea.html create mode 100644 editor/libeditor/tests/test_pasteImgTextarea.xhtml create mode 100644 editor/libeditor/tests/test_paste_as_quote_in_text_control.html create mode 100644 editor/libeditor/tests/test_paste_no_formatting.html create mode 100644 editor/libeditor/tests/test_paste_redirect_focus_in_paste_event_listener.html create mode 100644 editor/libeditor/tests/test_pasting_in_root_element.xhtml create mode 100644 editor/libeditor/tests/test_pasting_in_temporarily_created_div_outside_body.html create mode 100644 editor/libeditor/tests/test_pasting_table_rows.html create mode 100644 editor/libeditor/tests/test_pasting_text_longer_than_maxlength.html create mode 100644 editor/libeditor/tests/test_resizers_appearance.html create mode 100644 editor/libeditor/tests/test_resizers_resizing_elements.html create mode 100644 editor/libeditor/tests/test_root_element_replacement.html create mode 100644 editor/libeditor/tests/test_sanitizer_on_paste.html create mode 100644 editor/libeditor/tests/test_select_all_without_body.html create mode 100644 editor/libeditor/tests/test_selection_move_commands.html create mode 100644 editor/libeditor/tests/test_setting_value_longer_than_maxlength_with_setUserInput.html create mode 100644 editor/libeditor/tests/test_spellcheck_pref.html create mode 100644 editor/libeditor/tests/test_state_change_on_reframe.html create mode 100644 editor/libeditor/tests/test_textarea_value_not_include_cr.html create mode 100644 editor/libeditor/tests/test_texteditor_keyevent_handling.html create mode 100644 editor/libeditor/tests/test_texteditor_textnode.html create mode 100644 editor/libeditor/tests/test_texteditor_tripleclick_setvalue.html create mode 100644 editor/libeditor/tests/test_texteditor_wrapping_long_line.html create mode 100644 editor/libeditor/tests/test_typing_at_edge_of_anchor.html create mode 100644 editor/libeditor/tests/test_undo_after_spellchecker_replaces_word.html create mode 100644 editor/libeditor/tests/test_undo_redo_stack_after_setting_value.html create mode 100644 editor/libeditor/tests/test_undo_with_editingui.html (limited to 'editor/libeditor') diff --git a/editor/libeditor/AutoRangeArray.cpp b/editor/libeditor/AutoRangeArray.cpp new file mode 100644 index 0000000000..bff0806a8d --- /dev/null +++ b/editor/libeditor/AutoRangeArray.cpp @@ -0,0 +1,1195 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +#include "AutoRangeArray.h" + +#include "EditorDOMPoint.h" // for EditorDOMPoint, EditorDOMRange, etc +#include "EditorForwards.h" // for CollectChildrenOptions +#include "HTMLEditUtils.h" // for HTMLEditUtils +#include "HTMLEditHelpers.h" // for SplitNodeResult +#include "WSRunObject.h" // for WSRunScanner + +#include "mozilla/OwningNonNull.h" // for OwningNonNull +#include "mozilla/dom/Document.h" // for dom::Document +#include "mozilla/dom/HTMLBRElement.h" // for dom HTMLBRElement +#include "mozilla/dom/Selection.h" // for dom::Selection +#include "mozilla/dom/Text.h" // for dom::Text + +#include "gfxFontUtils.h" // for gfxFontUtils +#include "nsError.h" // for NS_SUCCESS_* and NS_ERROR_* +#include "nsFrameSelection.h" // for nsFrameSelection +#include "nsIContent.h" // for nsIContent +#include "nsINode.h" // for nsINode +#include "nsRange.h" // for nsRange +#include "nsTextFragment.h" // for nsTextFragment + +namespace mozilla { + +using namespace dom; + +/****************************************************************************** + * mozilla::AutoRangeArray + *****************************************************************************/ + +template AutoRangeArray::AutoRangeArray(const EditorDOMRange& aRange); +template AutoRangeArray::AutoRangeArray(const EditorRawDOMRange& aRange); +template AutoRangeArray::AutoRangeArray(const EditorDOMPoint& aRange); +template AutoRangeArray::AutoRangeArray(const EditorRawDOMPoint& aRange); + +AutoRangeArray::AutoRangeArray(const dom::Selection& aSelection) { + Initialize(aSelection); +} + +AutoRangeArray::AutoRangeArray(const AutoRangeArray& aOther) + : mAnchorFocusRange(aOther.mAnchorFocusRange), + mDirection(aOther.mDirection) { + mRanges.SetCapacity(aOther.mRanges.Length()); + for (const OwningNonNull& range : aOther.mRanges) { + RefPtr clonedRange = range->CloneRange(); + mRanges.AppendElement(std::move(clonedRange)); + } + mAnchorFocusRange = aOther.mAnchorFocusRange; +} + +template +AutoRangeArray::AutoRangeArray(const EditorDOMRangeBase& aRange) { + MOZ_ASSERT(aRange.IsPositionedAndValid()); + RefPtr range = aRange.CreateRange(IgnoreErrors()); + if (NS_WARN_IF(!range) || NS_WARN_IF(!range->IsPositioned())) { + return; + } + mRanges.AppendElement(*range); + mAnchorFocusRange = std::move(range); +} + +template +AutoRangeArray::AutoRangeArray(const EditorDOMPointBase& aPoint) { + MOZ_ASSERT(aPoint.IsSetAndValid()); + RefPtr range = aPoint.CreateCollapsedRange(IgnoreErrors()); + if (NS_WARN_IF(!range) || NS_WARN_IF(!range->IsPositioned())) { + return; + } + mRanges.AppendElement(*range); + mAnchorFocusRange = std::move(range); +} + +AutoRangeArray::~AutoRangeArray() { + if (mSavedRanges.isSome()) { + ClearSavedRanges(); + } +} + +// static +bool AutoRangeArray::IsEditableRange(const dom::AbstractRange& aRange, + const Element& aEditingHost) { + // TODO: Perhaps, we should check whether the start/end boundaries are + // first/last point of non-editable element. + // See https://github.com/w3c/editing/issues/283#issuecomment-788654850 + EditorRawDOMPoint atStart(aRange.StartRef()); + const bool isStartEditable = + atStart.IsInContentNode() && + EditorUtils::IsEditableContent(*atStart.ContainerAs(), + EditorUtils::EditorType::HTML) && + !HTMLEditUtils::IsNonEditableReplacedContent( + *atStart.ContainerAs()); + if (!isStartEditable) { + return false; + } + + if (aRange.GetStartContainer() != aRange.GetEndContainer()) { + EditorRawDOMPoint atEnd(aRange.EndRef()); + const bool isEndEditable = + atEnd.IsInContentNode() && + EditorUtils::IsEditableContent(*atEnd.ContainerAs(), + EditorUtils::EditorType::HTML) && + !HTMLEditUtils::IsNonEditableReplacedContent( + *atEnd.ContainerAs()); + if (!isEndEditable) { + return false; + } + + // Now, both start and end points are editable, but if they are in + // different editing host, we cannot edit the range. + if (atStart.ContainerAs() != atEnd.ContainerAs() && + atStart.ContainerAs()->GetEditingHost() != + atEnd.ContainerAs()->GetEditingHost()) { + return false; + } + } + + // HTMLEditor does not support modifying outside `` element for now. + nsINode* commonAncestor = aRange.GetClosestCommonInclusiveAncestor(); + return commonAncestor && commonAncestor->IsContent() && + commonAncestor->IsInclusiveDescendantOf(&aEditingHost); +} + +void AutoRangeArray::EnsureOnlyEditableRanges(const Element& aEditingHost) { + for (size_t i = mRanges.Length(); i > 0; i--) { + const OwningNonNull& range = mRanges[i - 1]; + if (!AutoRangeArray::IsEditableRange(range, aEditingHost)) { + mRanges.RemoveElementAt(i - 1); + continue; + } + // Special handling for `inert` attribute. If anchor node is inert, the + // range should be treated as not editable. + nsIContent* anchorContent = + mDirection == eDirNext + ? nsIContent::FromNode(range->GetStartContainer()) + : nsIContent::FromNode(range->GetEndContainer()); + if (anchorContent && HTMLEditUtils::ContentIsInert(*anchorContent)) { + mRanges.RemoveElementAt(i - 1); + continue; + } + // Additionally, if focus node is inert, the range should be collapsed to + // anchor node. + nsIContent* focusContent = + mDirection == eDirNext + ? nsIContent::FromNode(range->GetEndContainer()) + : nsIContent::FromNode(range->GetStartContainer()); + if (focusContent && focusContent != anchorContent && + HTMLEditUtils::ContentIsInert(*focusContent)) { + range->Collapse(mDirection == eDirNext); + } + } + mAnchorFocusRange = mRanges.IsEmpty() ? nullptr : mRanges.LastElement().get(); +} + +void AutoRangeArray::EnsureRangesInTextNode(const Text& aTextNode) { + auto GetOffsetInTextNode = [&aTextNode](const nsINode* aNode, + uint32_t aOffset) -> uint32_t { + MOZ_DIAGNOSTIC_ASSERT(aNode); + if (aNode == &aTextNode) { + return aOffset; + } + const nsIContent* anonymousDivElement = aTextNode.GetParent(); + MOZ_DIAGNOSTIC_ASSERT(anonymousDivElement); + MOZ_DIAGNOSTIC_ASSERT(anonymousDivElement->IsHTMLElement(nsGkAtoms::div)); + MOZ_DIAGNOSTIC_ASSERT(anonymousDivElement->GetFirstChild() == &aTextNode); + if (aNode == anonymousDivElement && aOffset == 0u) { + return 0u; // Point before the text node so that use start of the text. + } + MOZ_DIAGNOSTIC_ASSERT(aNode->IsInclusiveDescendantOf(anonymousDivElement)); + // Point after the text node so that use end of the text. + return aTextNode.TextDataLength(); + }; + for (uint32_t i : IntegerRange(mRanges.Length())) { + const OwningNonNull& range = mRanges[i]; + if (MOZ_LIKELY(range->GetStartContainer() == &aTextNode && + range->GetEndContainer() == &aTextNode)) { + continue; + } + range->SetStartAndEnd( + const_cast(&aTextNode), + GetOffsetInTextNode(range->GetStartContainer(), range->StartOffset()), + const_cast(&aTextNode), + GetOffsetInTextNode(range->GetEndContainer(), range->EndOffset())); + } + + if (MOZ_UNLIKELY(mRanges.Length() >= 2)) { + // For avoiding to handle same things in same range, we should drop and + // merge unnecessary ranges. Note that the ranges never overlap + // because selection ranges are not allowed it so that we need to check only + // end offset vs start offset of next one. + for (uint32_t i : Reversed(IntegerRange(mRanges.Length() - 1u))) { + MOZ_ASSERT(mRanges[i]->EndOffset() < mRanges[i + 1]->StartOffset()); + // XXX Should we delete collapsed range unless the index is 0? Without + // Selection API, such situation cannot happen so that `TextEditor` + // may behave unexpectedly. + if (MOZ_UNLIKELY(mRanges[i]->EndOffset() >= + mRanges[i + 1]->StartOffset())) { + const uint32_t newEndOffset = mRanges[i + 1]->EndOffset(); + mRanges.RemoveElementAt(i + 1); + if (MOZ_UNLIKELY(NS_WARN_IF(newEndOffset > mRanges[i]->EndOffset()))) { + // So, this case shouldn't happen. + mRanges[i]->SetStartAndEnd( + const_cast(&aTextNode), mRanges[i]->StartOffset(), + const_cast(&aTextNode), newEndOffset); + } + } + } + } +} + +Result +AutoRangeArray::ExtendAnchorFocusRangeFor( + const EditorBase& aEditorBase, nsIEditor::EDirection aDirectionAndAmount) { + MOZ_ASSERT(aEditorBase.IsEditActionDataAvailable()); + MOZ_ASSERT(mAnchorFocusRange); + MOZ_ASSERT(mAnchorFocusRange->IsPositioned()); + MOZ_ASSERT(mAnchorFocusRange->StartRef().IsSet()); + MOZ_ASSERT(mAnchorFocusRange->EndRef().IsSet()); + + if (!EditorUtils::IsFrameSelectionRequiredToExtendSelection( + aDirectionAndAmount, *this)) { + return aDirectionAndAmount; + } + + if (NS_WARN_IF(!aEditorBase.SelectionRef().RangeCount())) { + return Err(NS_ERROR_FAILURE); + } + + // By a preceding call of EnsureOnlyEditableRanges(), anchor/focus range may + // have been changed. In that case, we cannot use nsFrameSelection anymore. + // FIXME: We should make `nsFrameSelection::CreateRangeExtendedToSomewhere` + // work without `Selection` instance. + if (MOZ_UNLIKELY( + aEditorBase.SelectionRef().GetAnchorFocusRange()->StartRef() != + mAnchorFocusRange->StartRef() || + aEditorBase.SelectionRef().GetAnchorFocusRange()->EndRef() != + mAnchorFocusRange->EndRef())) { + return aDirectionAndAmount; + } + + RefPtr frameSelection = + aEditorBase.SelectionRef().GetFrameSelection(); + if (NS_WARN_IF(!frameSelection)) { + return Err(NS_ERROR_NOT_INITIALIZED); + } + + RefPtr editingHost; + if (aEditorBase.IsHTMLEditor()) { + editingHost = aEditorBase.AsHTMLEditor()->ComputeEditingHost(); + if (!editingHost) { + return Err(NS_ERROR_FAILURE); + } + } + + Result, nsresult> result(NS_ERROR_UNEXPECTED); + nsIEditor::EDirection directionAndAmountResult = aDirectionAndAmount; + switch (aDirectionAndAmount) { + case nsIEditor::eNextWord: + result = frameSelection->CreateRangeExtendedToNextWordBoundary(); + if (NS_WARN_IF(aEditorBase.Destroyed())) { + return Err(NS_ERROR_EDITOR_DESTROYED); + } + NS_WARNING_ASSERTION( + result.isOk(), + "nsFrameSelection::CreateRangeExtendedToNextWordBoundary() failed"); + // DeleteSelectionWithTransaction() doesn't handle these actions + // because it's inside batching, so don't confuse it: + directionAndAmountResult = nsIEditor::eNone; + break; + case nsIEditor::ePreviousWord: + result = + frameSelection->CreateRangeExtendedToPreviousWordBoundary(); + if (NS_WARN_IF(aEditorBase.Destroyed())) { + return Err(NS_ERROR_EDITOR_DESTROYED); + } + NS_WARNING_ASSERTION( + result.isOk(), + "nsFrameSelection::CreateRangeExtendedToPreviousWordBoundary() " + "failed"); + // DeleteSelectionWithTransaction() doesn't handle these actions + // because it's inside batching, so don't confuse it: + directionAndAmountResult = nsIEditor::eNone; + break; + case nsIEditor::eNext: + result = + frameSelection + ->CreateRangeExtendedToNextGraphemeClusterBoundary(); + if (NS_WARN_IF(aEditorBase.Destroyed())) { + return Err(NS_ERROR_EDITOR_DESTROYED); + } + NS_WARNING_ASSERTION(result.isOk(), + "nsFrameSelection::" + "CreateRangeExtendedToNextGraphemeClusterBoundary() " + "failed"); + // Don't set directionAndAmount to eNone (see Bug 502259) + break; + case nsIEditor::ePrevious: { + // Only extend the selection where the selection is after a UTF-16 + // surrogate pair or a variation selector. + // For other cases we don't want to do that, in order + // to make sure that pressing backspace will only delete the last + // typed character. + // XXX This is odd if the previous one is a sequence for a grapheme + // cluster. + const auto atStartOfSelection = GetFirstRangeStartPoint(); + if (MOZ_UNLIKELY(NS_WARN_IF(!atStartOfSelection.IsSet()))) { + return Err(NS_ERROR_FAILURE); + } + + // node might be anonymous DIV, so we find better text node + const EditorDOMPoint insertionPoint = + aEditorBase.FindBetterInsertionPoint(atStartOfSelection); + if (MOZ_UNLIKELY(!insertionPoint.IsSet())) { + NS_WARNING( + "EditorBase::FindBetterInsertionPoint() failed, but ignored"); + return aDirectionAndAmount; + } + + if (!insertionPoint.IsInTextNode()) { + return aDirectionAndAmount; + } + + const nsTextFragment* data = + &insertionPoint.ContainerAs()->TextFragment(); + uint32_t offset = insertionPoint.Offset(); + if (!(offset > 1 && + data->IsLowSurrogateFollowingHighSurrogateAt(offset - 1)) && + !(offset > 0 && + gfxFontUtils::IsVarSelector(data->CharAt(offset - 1)))) { + return aDirectionAndAmount; + } + // Different from the `eNext` case, we look for character boundary. + // I'm not sure whether this inconsistency between "Delete" and + // "Backspace" is intentional or not. + result = frameSelection + ->CreateRangeExtendedToPreviousCharacterBoundary(); + if (NS_WARN_IF(aEditorBase.Destroyed())) { + return Err(NS_ERROR_EDITOR_DESTROYED); + } + NS_WARNING_ASSERTION( + result.isOk(), + "nsFrameSelection::" + "CreateRangeExtendedToPreviousGraphemeClusterBoundary() failed"); + break; + } + case nsIEditor::eToBeginningOfLine: + result = + frameSelection->CreateRangeExtendedToPreviousHardLineBreak(); + if (NS_WARN_IF(aEditorBase.Destroyed())) { + return Err(NS_ERROR_EDITOR_DESTROYED); + } + NS_WARNING_ASSERTION( + result.isOk(), + "nsFrameSelection::CreateRangeExtendedToPreviousHardLineBreak() " + "failed"); + directionAndAmountResult = nsIEditor::eNone; + break; + case nsIEditor::eToEndOfLine: + result = + frameSelection->CreateRangeExtendedToNextHardLineBreak(); + if (NS_WARN_IF(aEditorBase.Destroyed())) { + return Err(NS_ERROR_EDITOR_DESTROYED); + } + NS_WARNING_ASSERTION( + result.isOk(), + "nsFrameSelection::CreateRangeExtendedToNextHardLineBreak() failed"); + directionAndAmountResult = nsIEditor::eNext; + break; + default: + return aDirectionAndAmount; + } + + if (result.isErr()) { + return Err(result.inspectErr()); + } + RefPtr extendedRange(result.unwrap().forget()); + if (!extendedRange || NS_WARN_IF(!extendedRange->IsPositioned())) { + NS_WARNING("Failed to extend the range, but ignored"); + return directionAndAmountResult; + } + + // If the new range isn't editable, keep using the original range. + if (aEditorBase.IsHTMLEditor() && + !AutoRangeArray::IsEditableRange(*extendedRange, *editingHost)) { + return aDirectionAndAmount; + } + + if (NS_WARN_IF(!frameSelection->IsValidSelectionPoint( + extendedRange->GetStartContainer())) || + NS_WARN_IF(!frameSelection->IsValidSelectionPoint( + extendedRange->GetEndContainer()))) { + NS_WARNING("A range was extended to outer of selection limiter"); + return Err(NS_ERROR_FAILURE); + } + + // Swap focus/anchor range with the extended range. + DebugOnly found = false; + for (OwningNonNull& range : mRanges) { + if (range == mAnchorFocusRange) { + range = *extendedRange; + found = true; + break; + } + } + MOZ_ASSERT(found); + mAnchorFocusRange.swap(extendedRange); + return directionAndAmountResult; +} + +Result +AutoRangeArray::ShrinkRangesIfStartFromOrEndAfterAtomicContent( + const HTMLEditor& aHTMLEditor, nsIEditor::EDirection aDirectionAndAmount, + IfSelectingOnlyOneAtomicContent aIfSelectingOnlyOneAtomicContent, + const Element* aEditingHost) { + if (IsCollapsed()) { + return false; + } + + switch (aDirectionAndAmount) { + case nsIEditor::eNext: + case nsIEditor::eNextWord: + case nsIEditor::ePrevious: + case nsIEditor::ePreviousWord: + break; + default: + return false; + } + + bool changed = false; + for (auto& range : mRanges) { + MOZ_ASSERT(!range->IsInAnySelection(), + "Changing range in selection may cause running script"); + Result result = + WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent( + aHTMLEditor, range, aEditingHost); + if (result.isErr()) { + NS_WARNING( + "WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent() " + "failed"); + return Err(result.inspectErr()); + } + changed |= result.inspect(); + } + + if (mRanges.Length() == 1 && aIfSelectingOnlyOneAtomicContent == + IfSelectingOnlyOneAtomicContent::Collapse) { + MOZ_ASSERT(mRanges[0].get() == mAnchorFocusRange.get()); + if (mAnchorFocusRange->GetStartContainer() == + mAnchorFocusRange->GetEndContainer() && + mAnchorFocusRange->GetChildAtStartOffset() && + mAnchorFocusRange->StartRef().GetNextSiblingOfChildAtOffset() == + mAnchorFocusRange->GetChildAtEndOffset()) { + mAnchorFocusRange->Collapse(aDirectionAndAmount == nsIEditor::eNext || + aDirectionAndAmount == nsIEditor::eNextWord); + changed = true; + } + } + + return changed; +} + +bool AutoRangeArray::SaveAndTrackRanges(HTMLEditor& aHTMLEditor) { + if (mSavedRanges.isSome()) { + return false; + } + mSavedRanges.emplace(*this); + aHTMLEditor.RangeUpdaterRef().RegisterSelectionState(mSavedRanges.ref()); + mTrackingHTMLEditor = &aHTMLEditor; + return true; +} + +void AutoRangeArray::ClearSavedRanges() { + if (mSavedRanges.isNothing()) { + return; + } + OwningNonNull htmlEditor(std::move(mTrackingHTMLEditor)); + MOZ_ASSERT(!mTrackingHTMLEditor); + htmlEditor->RangeUpdaterRef().DropSelectionState(mSavedRanges.ref()); + mSavedRanges.reset(); +} + +// static +void AutoRangeArray:: + UpdatePointsToSelectAllChildrenIfCollapsedInEmptyBlockElement( + EditorDOMPoint& aStartPoint, EditorDOMPoint& aEndPoint, + const Element& aEditingHost) { + // FYI: This was moved from + // https://searchfox.org/mozilla-central/rev/3419858c997f422e3e70020a46baae7f0ec6dacc/editor/libeditor/HTMLEditSubActionHandler.cpp#6743 + + // MOOSE major hack: + // The GetPointAtFirstContentOfLineOrParentBlockIfFirstContentOfBlock() and + // GetPointAfterFollowingLineBreakOrAtFollowingBlock() don't really do the + // right thing for collapsed ranges inside block elements that contain nothing + // but a solo
. It's easier/ to put a workaround here than to revamp + // them. :-( + if (aStartPoint != aEndPoint) { + return; + } + + if (!aStartPoint.IsInContentNode()) { + return; + } + + // XXX Perhaps, this should be more careful. This may not select only one + // node because this just check whether the block is empty or not, + // and may not select in non-editable block. However, for inline + // editing host case, it's right to look for block element without + // editable state check. Now, this method is used for preparation for + // other things. So, cannot write test for this method behavior. + // So, perhaps, we should get rid of this method and each caller should + // handle its job better. + Element* const maybeNonEditableBlockElement = + HTMLEditUtils::GetInclusiveAncestorElement( + *aStartPoint.ContainerAs(), + HTMLEditUtils::ClosestBlockElement); + if (!maybeNonEditableBlockElement) { + return; + } + + // Make sure we don't go higher than our root element in the content tree + if (aEditingHost.IsInclusiveDescendantOf(maybeNonEditableBlockElement)) { + return; + } + + if (HTMLEditUtils::IsEmptyNode(*maybeNonEditableBlockElement)) { + aStartPoint.Set(maybeNonEditableBlockElement, 0u); + aEndPoint.SetToEndOf(maybeNonEditableBlockElement); + } +} + +/** + * Get the point before the line containing aPointInLine. + * + * @return If the line starts after a `
` element, returns next + * sibling of the `
` element. + * If the line is first line of a block, returns point of + * the block. + * NOTE: The result may be point of editing host. I.e., the container may be + * outside of editing host. + */ +static EditorDOMPoint +GetPointAtFirstContentOfLineOrParentBlockIfFirstContentOfBlock( + const EditorDOMPoint& aPointInLine, EditSubAction aEditSubAction, + const Element& aEditingHost) { + // FYI: This was moved from + // https://searchfox.org/mozilla-central/rev/3419858c997f422e3e70020a46baae7f0ec6dacc/editor/libeditor/HTMLEditSubActionHandler.cpp#6447 + + if (NS_WARN_IF(!aPointInLine.IsSet())) { + return EditorDOMPoint(); + } + + EditorDOMPoint point(aPointInLine); + // Start scanning from the container node if aPoint is in a text node. + // XXX Perhaps, IsInDataNode() must be expected. + if (point.IsInTextNode()) { + if (!point.GetContainer()->GetParentNode()) { + // Okay, can't promote any further + // XXX Why don't we return start of the text node? + return point; + } + // If there is a preformatted linefeed in the text node, let's return + // the point after it. + EditorDOMPoint atLastPreformattedNewLine = + HTMLEditUtils::GetPreviousPreformattedNewLineInTextNode( + point); + if (atLastPreformattedNewLine.IsSet()) { + return atLastPreformattedNewLine.NextPoint(); + } + point.Set(point.GetContainer()); + } + + // Look back through any further inline nodes that aren't across a
+ // from us, and that are enclosed in the same block. + // I.e., looking for start of current hard line. + constexpr HTMLEditUtils::WalkTreeOptions + ignoreNonEditableNodeAndStopAtBlockBoundary{ + HTMLEditUtils::WalkTreeOption::IgnoreNonEditableNode, + HTMLEditUtils::WalkTreeOption::StopAtBlockBoundary}; + for (nsIContent* previousEditableContent = HTMLEditUtils::GetPreviousContent( + point, ignoreNonEditableNodeAndStopAtBlockBoundary, &aEditingHost); + previousEditableContent && previousEditableContent->GetParentNode() && + !HTMLEditUtils::IsVisibleBRElement(*previousEditableContent) && + !HTMLEditUtils::IsBlockElement(*previousEditableContent); + previousEditableContent = HTMLEditUtils::GetPreviousContent( + point, ignoreNonEditableNodeAndStopAtBlockBoundary, &aEditingHost)) { + EditorDOMPoint atLastPreformattedNewLine = + HTMLEditUtils::GetPreviousPreformattedNewLineInTextNode( + EditorRawDOMPoint::AtEndOf(*previousEditableContent)); + if (atLastPreformattedNewLine.IsSet()) { + return atLastPreformattedNewLine.NextPoint(); + } + point.Set(previousEditableContent); + } + + // Finding the real start for this point unless current line starts after + //
element. Look up the tree for as long as we are the first node in + // the container (typically, start of nearest block ancestor), and as long + // as we haven't hit the body node. + for (nsIContent* nearContent = HTMLEditUtils::GetPreviousContent( + point, ignoreNonEditableNodeAndStopAtBlockBoundary, &aEditingHost); + !nearContent && !point.IsContainerHTMLElement(nsGkAtoms::body) && + point.GetContainerParent(); + nearContent = HTMLEditUtils::GetPreviousContent( + point, ignoreNonEditableNodeAndStopAtBlockBoundary, &aEditingHost)) { + // Don't keep looking up if we have found a blockquote element to act on + // when we handle outdent. + // XXX Sounds like this is hacky. If possible, it should be check in + // outdent handler for consistency between edit sub-actions. + // We should check Chromium's behavior of outdent when Selection + // starts from `
` and starts from first child of + // `
`. + if (aEditSubAction == EditSubAction::eOutdent && + point.IsContainerHTMLElement(nsGkAtoms::blockquote)) { + break; + } + + // Don't walk past the editable section. Note that we need to check + // before walking up to a parent because we need to return the parent + // object, so the parent itself might not be in the editable area, but + // it's OK if we're not performing a block-level action. + bool blockLevelAction = + aEditSubAction == EditSubAction::eIndent || + aEditSubAction == EditSubAction::eOutdent || + aEditSubAction == EditSubAction::eSetOrClearAlignment || + aEditSubAction == EditSubAction::eCreateOrRemoveBlock; + // XXX So, does this check whether the container is removable or not? It + // seems that here can be rewritten as obviously what here tries to + // check. + if (!point.GetContainerParent()->IsInclusiveDescendantOf(&aEditingHost) && + (blockLevelAction || + !point.GetContainer()->IsInclusiveDescendantOf(&aEditingHost))) { + break; + } + + point.Set(point.GetContainer()); + } + return point; +} + +/** + * Get the point after the following line break or the block which breaks the + * line containing aPointInLine. + * + * @return If the line ends with a visible `
` element, returns + * the point after the `
` element. + * If the line ends with a preformatted linefeed, returns + * the point after the linefeed unless it's an invisible + * line break immediately before a block boundary. + * If the line ends with a block boundary, returns the + * point of the block. + */ +static EditorDOMPoint GetPointAfterFollowingLineBreakOrAtFollowingBlock( + const EditorDOMPoint& aPointInLine, const Element& aEditingHost) { + // FYI: This was moved from + // https://searchfox.org/mozilla-central/rev/3419858c997f422e3e70020a46baae7f0ec6dacc/editor/libeditor/HTMLEditSubActionHandler.cpp#6541 + + if (NS_WARN_IF(!aPointInLine.IsSet())) { + return EditorDOMPoint(); + } + + EditorDOMPoint point(aPointInLine); + // Start scanning from the container node if aPoint is in a text node. + // XXX Perhaps, IsInDataNode() must be expected. + if (point.IsInTextNode()) { + if (NS_WARN_IF(!point.GetContainer()->GetParentNode())) { + // Okay, can't promote any further + // XXX Why don't we return end of the text node? + return point; + } + EditorDOMPoint atNextPreformattedNewLine = + HTMLEditUtils::GetInclusiveNextPreformattedNewLineInTextNode< + EditorDOMPoint>(point); + if (atNextPreformattedNewLine.IsSet()) { + // If the linefeed is last character of the text node, it may be + // invisible if it's immediately before a block boundary. In such + // case, we should retrun the block boundary. + Element* maybeNonEditableBlockElement = nullptr; + if (HTMLEditUtils::IsInvisiblePreformattedNewLine( + atNextPreformattedNewLine, &maybeNonEditableBlockElement) && + maybeNonEditableBlockElement) { + // If the block is a parent of the editing host, let's return end + // of editing host. + if (maybeNonEditableBlockElement == &aEditingHost || + !maybeNonEditableBlockElement->IsInclusiveDescendantOf( + &aEditingHost)) { + return EditorDOMPoint::AtEndOf(*maybeNonEditableBlockElement); + } + // If it's invisible because of parent block boundary, return end + // of the block. Otherwise, i.e., it's followed by a child block, + // returns the point of the child block. + if (atNextPreformattedNewLine.ContainerAs() + ->IsInclusiveDescendantOf(maybeNonEditableBlockElement)) { + return EditorDOMPoint::AtEndOf(*maybeNonEditableBlockElement); + } + return EditorDOMPoint(maybeNonEditableBlockElement); + } + // Otherwise, return the point after the preformatted linefeed. + return atNextPreformattedNewLine.NextPoint(); + } + // want to be after the text node + point.SetAfter(point.GetContainer()); + NS_WARNING_ASSERTION(point.IsSet(), "Failed to set to after the text node"); + } + + // Look ahead through any further inline nodes that aren't across a
from + // us, and that are enclosed in the same block. + // XXX Currently, we stop block-extending when finding visible
element. + // This might be different from "block-extend" of execCommand spec. + // However, the spec is really unclear. + // XXX Probably, scanning only editable nodes is wrong for + // EditSubAction::eCreateOrRemoveBlock because it might be better to wrap + // existing inline elements even if it's non-editable. For example, + // following examples with insertParagraph causes different result: + // *
foo[]bar
+ // *
foo[]bar
+ // *
foo[]barbaz
+ // Only in the first case, after the caret position isn't wrapped with + // new
element. + constexpr HTMLEditUtils::WalkTreeOptions + ignoreNonEditableNodeAndStopAtBlockBoundary{ + HTMLEditUtils::WalkTreeOption::IgnoreNonEditableNode, + HTMLEditUtils::WalkTreeOption::StopAtBlockBoundary}; + for (nsIContent* nextEditableContent = HTMLEditUtils::GetNextContent( + point, ignoreNonEditableNodeAndStopAtBlockBoundary, &aEditingHost); + nextEditableContent && + !HTMLEditUtils::IsBlockElement(*nextEditableContent) && + nextEditableContent->GetParent(); + nextEditableContent = HTMLEditUtils::GetNextContent( + point, ignoreNonEditableNodeAndStopAtBlockBoundary, &aEditingHost)) { + EditorDOMPoint atFirstPreformattedNewLine = + HTMLEditUtils::GetInclusiveNextPreformattedNewLineInTextNode< + EditorDOMPoint>(EditorRawDOMPoint(nextEditableContent, 0)); + if (atFirstPreformattedNewLine.IsSet()) { + // If the linefeed is last character of the text node, it may be + // invisible if it's immediately before a block boundary. In such + // case, we should retrun the block boundary. + Element* maybeNonEditableBlockElement = nullptr; + if (HTMLEditUtils::IsInvisiblePreformattedNewLine( + atFirstPreformattedNewLine, &maybeNonEditableBlockElement) && + maybeNonEditableBlockElement) { + // If the block is a parent of the editing host, let's return end + // of editing host. + if (maybeNonEditableBlockElement == &aEditingHost || + !maybeNonEditableBlockElement->IsInclusiveDescendantOf( + &aEditingHost)) { + return EditorDOMPoint::AtEndOf(*maybeNonEditableBlockElement); + } + // If it's invisible because of parent block boundary, return end + // of the block. Otherwise, i.e., it's followed by a child block, + // returns the point of the child block. + if (atFirstPreformattedNewLine.ContainerAs() + ->IsInclusiveDescendantOf(maybeNonEditableBlockElement)) { + return EditorDOMPoint::AtEndOf(*maybeNonEditableBlockElement); + } + return EditorDOMPoint(maybeNonEditableBlockElement); + } + // Otherwise, return the point after the preformatted linefeed. + return atFirstPreformattedNewLine.NextPoint(); + } + point.SetAfter(nextEditableContent); + if (NS_WARN_IF(!point.IsSet())) { + break; + } + if (HTMLEditUtils::IsVisibleBRElement(*nextEditableContent)) { + break; + } + } + + // Finding the real end for this point unless current line ends with a
+ // element. Look up the tree for as long as we are the last node in the + // container (typically, block node), and as long as we haven't hit the body + // node. + for (nsIContent* nearContent = HTMLEditUtils::GetNextContent( + point, ignoreNonEditableNodeAndStopAtBlockBoundary, &aEditingHost); + !nearContent && !point.IsContainerHTMLElement(nsGkAtoms::body) && + point.GetContainerParent(); + nearContent = HTMLEditUtils::GetNextContent( + point, ignoreNonEditableNodeAndStopAtBlockBoundary, &aEditingHost)) { + // Don't walk past the editable section. Note that we need to check before + // walking up to a parent because we need to return the parent object, so + // the parent itself might not be in the editable area, but it's OK. + // XXX Maybe returning parent of editing host is really error prone since + // everybody need to check whether the end point is in editing host + // when they touch there. + if (!point.GetContainer()->IsInclusiveDescendantOf(&aEditingHost) && + !point.GetContainerParent()->IsInclusiveDescendantOf(&aEditingHost)) { + break; + } + + point.SetAfter(point.GetContainer()); + if (NS_WARN_IF(!point.IsSet())) { + break; + } + } + return point; +} + +void AutoRangeArray::ExtendRangesToWrapLinesToHandleBlockLevelEditAction( + EditSubAction aEditSubAction, const Element& aEditingHost) { + // FYI: This is originated in + // https://searchfox.org/mozilla-central/rev/1739f1301d658c9bff544a0a095ab11fca2e549d/editor/libeditor/HTMLEditSubActionHandler.cpp#6712 + + bool removeSomeRanges = false; + for (OwningNonNull& range : mRanges) { + // Remove non-positioned ranges. + if (MOZ_UNLIKELY(!range->IsPositioned())) { + removeSomeRanges = true; + continue; + } + // If the range is native anonymous subtrees, we must meet a bug of + // `Selection` so that we need to hack here. + if (MOZ_UNLIKELY(range->GetStartContainer()->IsInNativeAnonymousSubtree() || + range->GetEndContainer()->IsInNativeAnonymousSubtree())) { + EditorRawDOMRange rawRange(range); + if (!rawRange.EnsureNotInNativeAnonymousSubtree()) { + range->Reset(); + removeSomeRanges = true; + continue; + } + if (NS_FAILED( + range->SetStartAndEnd(rawRange.StartRef().ToRawRangeBoundary(), + rawRange.EndRef().ToRawRangeBoundary())) || + MOZ_UNLIKELY(!range->IsPositioned())) { + range->Reset(); + removeSomeRanges = true; + continue; + } + } + // Finally, extend the range. + if (NS_FAILED(ExtendRangeToWrapStartAndEndLinesContainingBoundaries( + range, aEditSubAction, aEditingHost))) { + // If we failed to extend the range, we should use the original range + // as-is unless the range is broken at setting the range. + if (NS_WARN_IF(!range->IsPositioned())) { + removeSomeRanges = true; + } + } + } + if (removeSomeRanges) { + for (size_t i : Reversed(IntegerRange(mRanges.Length()))) { + if (!mRanges[i]->IsPositioned()) { + mRanges.RemoveElementAt(i); + } + } + if (!mAnchorFocusRange || !mAnchorFocusRange->IsPositioned()) { + if (mRanges.IsEmpty()) { + mAnchorFocusRange = nullptr; + } else { + mAnchorFocusRange = mRanges.LastElement(); + } + } + } +} + +// static +nsresult AutoRangeArray::ExtendRangeToWrapStartAndEndLinesContainingBoundaries( + nsRange& aRange, EditSubAction aEditSubAction, + const Element& aEditingHost) { + MOZ_DIAGNOSTIC_ASSERT( + !EditorRawDOMPoint(aRange.StartRef()).IsInNativeAnonymousSubtree()); + MOZ_DIAGNOSTIC_ASSERT( + !EditorRawDOMPoint(aRange.EndRef()).IsInNativeAnonymousSubtree()); + + if (NS_WARN_IF(!aRange.IsPositioned())) { + return NS_ERROR_INVALID_ARG; + } + + EditorDOMPoint startPoint(aRange.StartRef()), endPoint(aRange.EndRef()); + AutoRangeArray::UpdatePointsToSelectAllChildrenIfCollapsedInEmptyBlockElement( + startPoint, endPoint, aEditingHost); + + // Make a new adjusted range to represent the appropriate block content. + // This is tricky. The basic idea is to push out the range endpoints to + // truly enclose the blocks that we will affect. + + // Make sure that the new range ends up to be in the editable section. + // XXX Looks like that this check wastes the time. Perhaps, we should + // implement a method which checks both two DOM points in the editor + // root. + + startPoint = GetPointAtFirstContentOfLineOrParentBlockIfFirstContentOfBlock( + startPoint, aEditSubAction, aEditingHost); + // XXX GetPointAtFirstContentOfLineOrParentBlockIfFirstContentOfBlock() may + // return point of editing host. Perhaps, we should change it and stop + // checking it here since this check may be expensive. + // XXX If the container is an element in the editing host but it points end of + // the container, this returns nullptr. Is it intentional? + if (!startPoint.GetChildOrContainerIfDataNode() || + !startPoint.GetChildOrContainerIfDataNode()->IsInclusiveDescendantOf( + &aEditingHost)) { + return NS_ERROR_FAILURE; + } + endPoint = + GetPointAfterFollowingLineBreakOrAtFollowingBlock(endPoint, aEditingHost); + const EditorDOMPoint lastRawPoint = + endPoint.IsStartOfContainer() ? endPoint : endPoint.PreviousPoint(); + // XXX GetPointAfterFollowingLineBreakOrAtFollowingBlock() may return point of + // editing host. Perhaps, we should change it and stop checking it here + // since this check may be expensive. + // XXX If the container is an element in the editing host but it points end of + // the container, this returns nullptr. Is it intentional? + if (!lastRawPoint.GetChildOrContainerIfDataNode() || + !lastRawPoint.GetChildOrContainerIfDataNode()->IsInclusiveDescendantOf( + &aEditingHost)) { + return NS_ERROR_FAILURE; + } + + nsresult rv = aRange.SetStartAndEnd(startPoint.ToRawRangeBoundary(), + endPoint.ToRawRangeBoundary()); + if (NS_FAILED(rv)) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +Result +AutoRangeArray::SplitTextAtEndBoundariesAndInlineAncestorsAtBothBoundaries( + HTMLEditor& aHTMLEditor, const Element& aEditingHost, + const nsIContent* aAncestorLimiter /* = nullptr */) { + // FYI: The following code is originated in + // https://searchfox.org/mozilla-central/rev/c8e15e17bc6fd28f558c395c948a6251b38774ff/editor/libeditor/HTMLEditSubActionHandler.cpp#6971 + + // Split text nodes. This is necessary, since given ranges may end in text + // nodes in case where part of a pre-formatted elements needs to be moved. + EditorDOMPoint pointToPutCaret; + IgnoredErrorResult ignoredError; + for (const OwningNonNull& range : mRanges) { + EditorDOMPoint atEnd(range->EndRef()); + if (NS_WARN_IF(!atEnd.IsSet()) || !atEnd.IsInTextNode() || + atEnd.GetContainer() == aAncestorLimiter) { + continue; + } + + if (!atEnd.IsStartOfContainer() && !atEnd.IsEndOfContainer()) { + // Split the text node. + Result splitAtEndResult = + aHTMLEditor.SplitNodeWithTransaction(atEnd); + if (MOZ_UNLIKELY(splitAtEndResult.isErr())) { + NS_WARNING("HTMLEditor::SplitNodeWithTransaction() failed"); + return splitAtEndResult.propagateErr(); + } + SplitNodeResult unwrappedSplitAtEndResult = splitAtEndResult.unwrap(); + unwrappedSplitAtEndResult.MoveCaretPointTo( + pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion}); + + // Correct the range. + // The new end parent becomes the parent node of the text. + MOZ_ASSERT(!range->IsInAnySelection()); + range->SetEnd(unwrappedSplitAtEndResult.AtNextContent() + .ToRawRangeBoundary(), + ignoredError); + NS_WARNING_ASSERTION(!ignoredError.Failed(), + "nsRange::SetEnd() failed, but ignored"); + ignoredError.SuppressException(); + } + } + + // FYI: The following code is originated in + // https://searchfox.org/mozilla-central/rev/c8e15e17bc6fd28f558c395c948a6251b38774ff/editor/libeditor/HTMLEditSubActionHandler.cpp#7023 + AutoTArray, 8> rangeItemArray; + rangeItemArray.AppendElements(mRanges.Length()); + + // First register ranges for special editor gravity + Maybe anchorFocusRangeIndex; + for (size_t index : IntegerRange(rangeItemArray.Length())) { + rangeItemArray[index] = new RangeItem(); + rangeItemArray[index]->StoreRange(*mRanges[index]); + aHTMLEditor.RangeUpdaterRef().RegisterRangeItem(*rangeItemArray[index]); + if (mRanges[index] == mAnchorFocusRange) { + anchorFocusRangeIndex = Some(index); + } + } + // TODO: We should keep the array, and just update the ranges. + mRanges.Clear(); + mAnchorFocusRange = nullptr; + // Now bust up inlines. + nsresult rv = NS_OK; + for (OwningNonNull& item : Reversed(rangeItemArray)) { + // MOZ_KnownLive because 'rangeItemArray' is guaranteed to keep it alive. + Result splitParentsResult = + aHTMLEditor.SplitParentInlineElementsAtRangeBoundaries( + MOZ_KnownLive(*item), aEditingHost, aAncestorLimiter); + if (MOZ_UNLIKELY(splitParentsResult.isErr())) { + NS_WARNING( + "HTMLEditor::SplitParentInlineElementsAtRangeBoundaries() failed"); + rv = splitParentsResult.unwrapErr(); + break; + } + if (splitParentsResult.inspect().IsSet()) { + pointToPutCaret = splitParentsResult.unwrap(); + } + } + // Then unregister the ranges + for (size_t index : IntegerRange(rangeItemArray.Length())) { + aHTMLEditor.RangeUpdaterRef().DropRangeItem(rangeItemArray[index]); + RefPtr range = rangeItemArray[index]->GetRange(); + if (range && range->IsPositioned()) { + if (anchorFocusRangeIndex.isSome() && index == *anchorFocusRangeIndex) { + mAnchorFocusRange = range; + } + mRanges.AppendElement(std::move(range)); + } + } + if (!mAnchorFocusRange && !mRanges.IsEmpty()) { + mAnchorFocusRange = mRanges.LastElement(); + } + + // XXX Why do we ignore the other errors here?? + if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) { + return Err(NS_ERROR_EDITOR_DESTROYED); + } + return pointToPutCaret; +} + +nsresult AutoRangeArray::CollectEditTargetNodes( + const HTMLEditor& aHTMLEditor, + nsTArray>& aOutArrayOfContents, + EditSubAction aEditSubAction, + CollectNonEditableNodes aCollectNonEditableNodes) const { + MOZ_ASSERT(aHTMLEditor.IsEditActionDataAvailable()); + + // FYI: This was moved from + // https://searchfox.org/mozilla-central/rev/4bce7d85ba4796dd03c5dcc7cfe8eee0e4c07b3b/editor/libeditor/HTMLEditSubActionHandler.cpp#7060 + + // Gather up a list of all the nodes + for (const OwningNonNull& range : mRanges) { + DOMSubtreeIterator iter; + nsresult rv = iter.Init(*range); + if (NS_FAILED(rv)) { + NS_WARNING("DOMSubtreeIterator::Init() failed"); + return rv; + } + if (aOutArrayOfContents.IsEmpty()) { + iter.AppendAllNodesToArray(aOutArrayOfContents); + } else { + AutoTArray, 24> arrayOfTopChildren; + iter.AppendNodesToArray( + +[](nsINode& aNode, void* aArray) -> bool { + MOZ_ASSERT(aArray); + return !static_cast>*>(aArray) + ->Contains(&aNode); + }, + arrayOfTopChildren, &aOutArrayOfContents); + aOutArrayOfContents.AppendElements(std::move(arrayOfTopChildren)); + } + if (aCollectNonEditableNodes == CollectNonEditableNodes::No) { + for (size_t i : Reversed(IntegerRange(aOutArrayOfContents.Length()))) { + if (!EditorUtils::IsEditableContent(aOutArrayOfContents[i], + EditorUtils::EditorType::HTML)) { + aOutArrayOfContents.RemoveElementAt(i); + } + } + } + } + + switch (aEditSubAction) { + case EditSubAction::eCreateOrRemoveBlock: { + // Certain operations should not act on li's and td's, but rather inside + // them. Alter the list as needed. + CollectChildrenOptions options = { + CollectChildrenOption::CollectListChildren, + CollectChildrenOption::CollectTableChildren}; + if (aCollectNonEditableNodes == CollectNonEditableNodes::No) { + options += CollectChildrenOption::IgnoreNonEditableChildren; + } + for (int32_t i = aOutArrayOfContents.Length() - 1; i >= 0; i--) { + OwningNonNull content = aOutArrayOfContents[i]; + if (HTMLEditUtils::IsListItem(content)) { + aOutArrayOfContents.RemoveElementAt(i); + HTMLEditUtils::CollectChildren(*content, aOutArrayOfContents, i, + options); + } + } + // Empty text node shouldn't be selected if unnecessary + for (int32_t i = aOutArrayOfContents.Length() - 1; i >= 0; i--) { + if (Text* text = aOutArrayOfContents[i]->GetAsText()) { + // Don't select empty text except to empty block + if (!HTMLEditUtils::IsVisibleTextNode(*text)) { + aOutArrayOfContents.RemoveElementAt(i); + } + } + } + break; + } + case EditSubAction::eCreateOrChangeList: { + // XXX aCollectNonEditableNodes is ignored here. Maybe a bug. + CollectChildrenOptions options = { + CollectChildrenOption::CollectTableChildren}; + for (size_t i = aOutArrayOfContents.Length(); i > 0; i--) { + // Scan for table elements. If we find table elements other than + // table, replace it with a list of any editable non-table content + // because if a selection range starts from end in a table-cell and + // ends at or starts from outside the ``, we need to make + // lists in each selected table-cells. + OwningNonNull content = aOutArrayOfContents[i - 1]; + if (HTMLEditUtils::IsAnyTableElementButNotTable(content)) { + aOutArrayOfContents.RemoveElementAt(i - 1); + HTMLEditUtils::CollectChildren(content, aOutArrayOfContents, i - 1, + options); + } + } + // If there is only one node in the array, and it is a `
`, + // `
` or a list element, then look inside of it until we + // find inner list or content. + if (aOutArrayOfContents.Length() != 1) { + break; + } + Element* deepestDivBlockquoteOrListElement = + HTMLEditUtils::GetInclusiveDeepestFirstChildWhichHasOneChild( + aOutArrayOfContents[0], + {HTMLEditUtils::WalkTreeOption::IgnoreNonEditableNode}, + nsGkAtoms::div, nsGkAtoms::blockquote, nsGkAtoms::ul, + nsGkAtoms::ol, nsGkAtoms::dl); + if (!deepestDivBlockquoteOrListElement) { + break; + } + if (deepestDivBlockquoteOrListElement->IsAnyOfHTMLElements( + nsGkAtoms::div, nsGkAtoms::blockquote)) { + aOutArrayOfContents.Clear(); + // XXX Before we're called, non-editable nodes are ignored. However, + // we may append non-editable nodes here. + HTMLEditUtils::CollectChildren(*deepestDivBlockquoteOrListElement, + aOutArrayOfContents, 0, {}); + break; + } + aOutArrayOfContents.ReplaceElementAt( + 0, OwningNonNull(*deepestDivBlockquoteOrListElement)); + break; + } + case EditSubAction::eOutdent: + case EditSubAction::eIndent: + case EditSubAction::eSetPositionToAbsolute: { + // Indent/outdent already do something special for list items, but we + // still need to make sure we don't act on table elements + CollectChildrenOptions options = { + CollectChildrenOption::CollectListChildren, + CollectChildrenOption::CollectTableChildren}; + if (aCollectNonEditableNodes == CollectNonEditableNodes::No) { + options += CollectChildrenOption::IgnoreNonEditableChildren; + } + for (int32_t i = aOutArrayOfContents.Length() - 1; i >= 0; i--) { + OwningNonNull content = aOutArrayOfContents[i]; + if (HTMLEditUtils::IsAnyTableElementButNotTable(content)) { + aOutArrayOfContents.RemoveElementAt(i); + HTMLEditUtils::CollectChildren(*content, aOutArrayOfContents, i, + options); + } + } + break; + } + default: + break; + } + + // Outdent should look inside of divs. + if (aEditSubAction == EditSubAction::eOutdent && + !aHTMLEditor.IsCSSEnabled()) { + CollectChildrenOptions options = {}; + if (aCollectNonEditableNodes == CollectNonEditableNodes::No) { + options += CollectChildrenOption::IgnoreNonEditableChildren; + } + for (int32_t i = aOutArrayOfContents.Length() - 1; i >= 0; i--) { + OwningNonNull content = aOutArrayOfContents[i]; + if (content->IsHTMLElement(nsGkAtoms::div)) { + aOutArrayOfContents.RemoveElementAt(i); + HTMLEditUtils::CollectChildren(*content, aOutArrayOfContents, i, + options); + } + } + } + + return NS_OK; +} + +Element* AutoRangeArray::GetClosestAncestorAnyListElementOfRange() const { + for (const OwningNonNull& range : mRanges) { + nsINode* commonAncestorNode = range->GetClosestCommonInclusiveAncestor(); + if (MOZ_UNLIKELY(!commonAncestorNode)) { + continue; + } + for (Element* element : + commonAncestorNode->InclusiveAncestorsOfType()) { + if (HTMLEditUtils::IsAnyListElement(element)) { + return element; + } + } + } + return nullptr; +} + +} // namespace mozilla diff --git a/editor/libeditor/AutoRangeArray.h b/editor/libeditor/AutoRangeArray.h new file mode 100644 index 0000000000..ff0f223663 --- /dev/null +++ b/editor/libeditor/AutoRangeArray.h @@ -0,0 +1,469 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +#ifndef AutoRangeArray_h +#define AutoRangeArray_h + +#include "EditAction.h" // for EditSubAction +#include "EditorBase.h" // for EditorBase +#include "EditorDOMPoint.h" // for EditorDOMPoint, EditorDOMRange, etc +#include "EditorForwards.h" +#include "SelectionState.h" // for SelectionState + +#include "mozilla/ErrorResult.h" // for ErrorResult +#include "mozilla/IntegerRange.h" // for IntegerRange +#include "mozilla/Maybe.h" // for Maybe +#include "mozilla/RangeBoundary.h" // for RangeBoundary +#include "mozilla/Result.h" // for Result<> +#include "mozilla/dom/Element.h" // for dom::Element +#include "mozilla/dom/HTMLBRElement.h" // for dom::HTMLBRElement +#include "mozilla/dom/Selection.h" // for dom::Selection +#include "mozilla/dom/Text.h" // for dom::Text + +#include "nsDebug.h" // for NS_WARNING, etc +#include "nsDirection.h" // for nsDirection +#include "nsError.h" // for NS_SUCCESS_* and NS_ERROR_* +#include "nsRange.h" // for nsRange + +namespace mozilla { + +/****************************************************************************** + * AutoRangeArray stores ranges which do no belong any `Selection`. + * So, different from `AutoSelectionRangeArray`, this can be used for + * ranges which may need to be modified before touching the DOM tree, + * but does not want to modify `Selection` for the performance. + *****************************************************************************/ +class MOZ_STACK_CLASS AutoRangeArray final { + public: + explicit AutoRangeArray(const dom::Selection& aSelection); + template + explicit AutoRangeArray(const EditorDOMRangeBase& aRange); + template + explicit AutoRangeArray(const EditorDOMPointBase& aPoint); + // The copy constructor copies everything except saved ranges. + explicit AutoRangeArray(const AutoRangeArray& aOther); + + ~AutoRangeArray(); + + void Initialize(const dom::Selection& aSelection) { + ClearSavedRanges(); + mDirection = aSelection.GetDirection(); + mRanges.Clear(); + for (const uint32_t i : IntegerRange(aSelection.RangeCount())) { + MOZ_ASSERT(aSelection.GetRangeAt(i)); + mRanges.AppendElement(aSelection.GetRangeAt(i)->CloneRange()); + if (aSelection.GetRangeAt(i) == aSelection.GetAnchorFocusRange()) { + mAnchorFocusRange = mRanges.LastElement(); + } + } + } + + /** + * Check whether all ranges in content nodes or not. If the ranges is empty, + * this returns false. + */ + [[nodiscard]] bool IsInContent() const { + if (mRanges.IsEmpty()) { + return false; + } + for (const OwningNonNull& range : mRanges) { + if (MOZ_UNLIKELY(!range->IsPositioned() || !range->GetStartContainer() || + !range->GetStartContainer()->IsContent() || + !range->GetEndContainer() || + !range->GetEndContainer()->IsContent())) { + return false; + } + } + return true; + } + + /** + * EnsureOnlyEditableRanges() removes ranges which cannot modify. + * Note that this is designed only for `HTMLEditor` because this must not + * be required by `TextEditor`. + */ + void EnsureOnlyEditableRanges(const dom::Element& aEditingHost); + + /** + * EnsureRangesInTextNode() is designed for TextEditor to guarantee that + * all ranges are in its text node which is first child of the anonymous
+ * element and is first child. + */ + void EnsureRangesInTextNode(const dom::Text& aTextNode); + + /** + * Extend ranges to wrap lines to handle block level edit actions such as + * updating the block parent or indent/outdent around the selection. + */ + void ExtendRangesToWrapLinesToHandleBlockLevelEditAction( + EditSubAction aEditSubAction, const dom::Element& aEditingHost); + + /** + * Check whether the range is in aEditingHost and both containers of start and + * end boundaries of the range are editable. + */ + [[nodiscard]] static bool IsEditableRange(const dom::AbstractRange& aRange, + const dom::Element& aEditingHost); + + /** + * Check whether the first range is in aEditingHost and both containers of + * start and end boundaries of the first range are editable. + */ + [[nodiscard]] bool IsFirstRangeEditable( + const dom::Element& aEditingHost) const { + return IsEditableRange(FirstRangeRef(), aEditingHost); + } + + /** + * IsAtLeastOneContainerOfRangeBoundariesInclusiveDescendantOf() returns true + * if at least one of the containers of the range boundaries is an inclusive + * descendant of aContent. + */ + [[nodiscard]] bool + IsAtLeastOneContainerOfRangeBoundariesInclusiveDescendantOf( + const nsIContent& aContent) const { + for (const OwningNonNull& range : mRanges) { + nsINode* startContainer = range->GetStartContainer(); + if (startContainer && + startContainer->IsInclusiveDescendantOf(&aContent)) { + return true; + } + nsINode* endContainer = range->GetEndContainer(); + if (startContainer == endContainer) { + continue; + } + if (endContainer && endContainer->IsInclusiveDescendantOf(&aContent)) { + return true; + } + } + return false; + } + + [[nodiscard]] auto& Ranges() { return mRanges; } + [[nodiscard]] const auto& Ranges() const { return mRanges; } + [[nodiscard]] OwningNonNull& FirstRangeRef() { return mRanges[0]; } + [[nodiscard]] const OwningNonNull& FirstRangeRef() const { + return mRanges[0]; + } + + template