test_command_state_when_readonly.html (5568B)
1 <!doctype html> 2 <title>Test for nsIEditor.isCommandEnabled for normal and read-only editors</title> 3 <script src="/tests/SimpleTest/SimpleTest.js"></script> 4 <script src="/tests/SimpleTest/EventUtils.js"></script> 5 <link rel="stylesheet" href="/tests/SimpleTest/test.css"> 6 <div contenteditable></div> 7 <script> 8 let node = document.querySelector("div"); 9 node.focus(); 10 let htmlEditor = 11 SpecialPowers.wrap(window).docShell.editingSession.getEditorForWindow(window); 12 13 // Supported environments for each command. Supported values for each 14 // environment property: 15 // content: "empty", "non-empty", "cleared" 16 // selected: true, false 17 // readonly: true, false 18 // 19 // If an environment definition does not state a certain property, the command 20 // supports all possible values for that property. The following definition: 21 // "cmd_copy": [{content: "non-empty", selected: true}], 22 // is equivalent to: 23 // "cmd_copy": [ 24 // {content: "non-empty", selected: true, readonly: true}, 25 // {content: "non-empty", selected: true, readonly: false}, 26 // ], 27 const TEST_COMMANDS = { 28 "cmd_selectAll": [{content: "non-empty"}], 29 30 "cmd_copy": [{content: "non-empty", selected: true}], 31 32 "cmd_cut": [{content: "non-empty", selected: true, readonly: false}], 33 "cmd_delete": [{content: "non-empty", selected: true, readonly: false}], 34 "cmd_removeList":[{content: "non-empty", selected: true, readonly: false}], 35 36 "cmd_undo": [{content: "cleared", readonly: false}], 37 "cmd_redo": [{content: "cleared", readonly: false}], 38 39 "cmd_switchTextDirection": [{readonly: false}], 40 "cmd_bold": [{readonly: false}], 41 "cmd_italic": [{readonly: false}], 42 "cmd_underline": [{readonly: false}], 43 "cmd_em": [{readonly: false}], 44 "cmd_strong": [{readonly: false}], 45 "cmd_strikethrough": [{readonly: false}], 46 "cmd_superscript": [{readonly: false}], 47 "cmd_subscript": [{readonly: false}], 48 "cmd_indent": [{readonly: false}], 49 "cmd_outdent": [{readonly: false}], 50 "cmd_formatBlock": [{readonly: false}], 51 "cmd_paragraphState": [{readonly: false}], 52 "cmd_fontFace": [{readonly: false}], 53 "cmd_fontSize": [{readonly: false}], 54 "cmd_fontColor": [{readonly: false}], 55 "cmd_backgroundColor": [{readonly: false}], 56 "cmd_highlight": [{readonly: false}], 57 "cmd_align": [{readonly: false}], 58 "cmd_removeStyles": [{readonly: false}], 59 "cmd_increaseFont": [{readonly: false}], 60 "cmd_decreaseFont": [{readonly: false}], 61 "cmd_insertHR": [{readonly: false}], 62 "cmd_insertHTML": [{readonly: false}], 63 "cmd_insertText": [{readonly: false}], 64 "cmd_insertParagraph": [{readonly: false}], 65 "cmd_insertLineBreak": [{readonly: false}], 66 "cmd_tt":[{readonly: false}], 67 "cmd_nobreak":[{readonly: false}], 68 "cmd_cite":[{readonly: false}], 69 "cmd_abbr":[{readonly: false}], 70 "cmd_acronym":[{readonly: false}], 71 "cmd_code":[{readonly: false}], 72 "cmd_samp":[{readonly: false}], 73 "cmd_var":[{readonly: false}], 74 "cmd_removeLinks":[{readonly: false}], 75 "cmd_ol":[{readonly: false}], 76 "cmd_ul":[{readonly: false}], 77 "cmd_dt":[{readonly: false}], 78 "cmd_dd":[{readonly: false}], 79 80 // InsertTagCommand 81 "cmd_insertImageNoUI": [{readonly: false}], 82 "cmd_insertLinkNoUI": [{readonly: false}], 83 }; 84 85 function testCommands(content) { 86 for (let readonly of [true, false]){ 87 if (readonly) { 88 htmlEditor.flags |= SpecialPowers.Ci.nsIEditor.eEditorReadonlyMask; 89 } else { 90 htmlEditor.flags &= ~SpecialPowers.Ci.nsIEditor.eEditorReadonlyMask; 91 } 92 93 for (let selected of [true, false]) { 94 let selection = window.getSelection(); 95 selection.collapse(node); 96 97 if (selected) { 98 if (content == "non-empty") { 99 // The command cmd_removeList needs selected text inside a list. It 100 // does not matter for all other commands, so lets just select that. 101 let range = document.createRange(); 102 let li = document.querySelector("li"); 103 range.selectNodeContents(li); 104 selection.removeAllRanges(); 105 selection.addRange(range); 106 } else { 107 document.execCommand("selectAll"); 108 } 109 } 110 111 for (let [cmd, supports] of Object.entries(TEST_COMMANDS)) { 112 // Check if the command should support this environment. 113 let expected = supports.some(supported => 114 content == (supported?.content ?? content) && 115 readonly == (supported?.readonly ?? readonly) && 116 selected == (supported?.selected ?? selected) 117 ) 118 is( 119 SpecialPowers.isCommandEnabled(window, cmd), 120 expected, 121 `Enabled state of command ${cmd} should be ${ 122 expected ? "TRUE" : "FALSE" 123 } for ${JSON.stringify({content, selected, readonly})}` 124 ); 125 } 126 } 127 } 128 } 129 130 testCommands("empty"); 131 132 // The cmd_removeList command needs a list. 133 node.innerHTML = "<ul><li><span>abcd</span></li></ul>"; 134 testCommands("non-empty"); 135 136 // Make some content modifications to enable undo and redo. 137 node.innerText = "ABC"; 138 is(node.innerText.trim(), "ABC", "phase 1"); 139 document.execCommand("selectAll"); 140 synthesizeKey("KEY_Backspace"); 141 is(node.innerText.trim(), "", "phase 2"); 142 synthesizeKey("3"); 143 is(node.innerText.trim(), "3", "phase 3"); 144 SpecialPowers.doCommand(window, "cmd_undo"); 145 is(node.innerText.trim(), "", "phase 4"); 146 147 node.innerHTML = ""; 148 testCommands("cleared"); 149 </script>