browser_rules_gridline-names-autocomplete.js (7374B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // Tests that CSS property values are autocompleted and cycled 7 // correctly when editing an existing property in the rule view. 8 9 // format : 10 // [ 11 // what key to press, 12 // modifers, 13 // expected input box value after keypress, 14 // flags: 15 // - is the popup open, 16 // - is a suggestion selected in the popup, 17 // - expect ruleview-changed, 18 // - expect grid-line-names-updated and popup to be closed and reopened, 19 // ] 20 21 const NONE = 0; 22 const OPEN = 1; 23 const SELECTED = 2; 24 const CHANGE = 4; 25 const SUBMIT_PROPERTY_NAME = 8; 26 27 const changeTestData = [ 28 ["c", {}, "col1-start", OPEN | SELECTED | CHANGE], 29 ["o", {}, "col1-start", OPEN | SELECTED | CHANGE], 30 ["l", {}, "col1-start", OPEN | SELECTED | CHANGE], 31 ["VK_DOWN", {}, "col2-start", OPEN | SELECTED | CHANGE], 32 ["VK_RIGHT", {}, "col2-start", NONE], 33 ]; 34 35 // Creates a new CSS property value. 36 // Checks that grid-area autocompletes column and row names. 37 const newAreaTestData = [ 38 ["g", {}, "gap", OPEN | SELECTED], 39 ["VK_DOWN", {}, "grid", OPEN | SELECTED], 40 ["VK_DOWN", {}, "grid-area", OPEN | SELECTED], 41 // When hitting Tab, the popup on the property name gets closed and the one on the 42 // property value opens (with the grid area names), without auto-selecting an item. 43 ["VK_TAB", {}, "", OPEN | SUBMIT_PROPERTY_NAME], 44 ["c", {}, "col1-start", OPEN | SELECTED | CHANGE], 45 ["VK_BACK_SPACE", {}, "c", CHANGE], 46 ["VK_BACK_SPACE", {}, "", OPEN | CHANGE], 47 ["r", {}, "revert", OPEN | SELECTED | CHANGE], 48 ["VK_DOWN", {}, "revert-layer", OPEN | SELECTED | CHANGE], 49 ["VK_DOWN", {}, "row1-start", OPEN | SELECTED | CHANGE], 50 ["r", {}, "rr", CHANGE], 51 ["VK_BACK_SPACE", {}, "r", CHANGE], 52 ["o", {}, "row1-start", OPEN | SELECTED | CHANGE], 53 ["VK_TAB", {}, "", CHANGE], 54 ]; 55 56 // Creates a new CSS property value. 57 // Checks that grid-row only autocompletes row names. 58 const newRowTestData = [ 59 ["g", {}, "gap", OPEN | SELECTED], 60 ["r", {}, "grid", OPEN | SELECTED], 61 ["i", {}, "grid", OPEN | SELECTED], 62 ["d", {}, "grid", OPEN | SELECTED], 63 ["-", {}, "grid-area", OPEN | SELECTED], 64 ["r", {}, "grid-row", OPEN | SELECTED], 65 // When hitting Tab, the popup on the property name gets closed and the one on the 66 // property value opens (with the grid area names), without auto-selecting an item. 67 ["VK_TAB", {}, "", OPEN | SUBMIT_PROPERTY_NAME], 68 ["c", {}, "c", CHANGE], 69 ["VK_BACK_SPACE", {}, "", OPEN | CHANGE], 70 ["r", {}, "revert", OPEN | SELECTED | CHANGE], 71 ["VK_DOWN", {}, "revert-layer", OPEN | SELECTED | CHANGE], 72 ["VK_DOWN", {}, "row1-start", OPEN | SELECTED | CHANGE], 73 ["VK_TAB", {}, "", CHANGE], 74 ]; 75 76 const TEST_URL = URL_ROOT + "doc_grid_names.html"; 77 78 add_task(async function () { 79 await addTab(TEST_URL); 80 const { toolbox, inspector, view } = await openRuleView(); 81 82 info("Test autocompletion changing a preexisting property"); 83 await runChangePropertyAutocompletionTest( 84 toolbox, 85 inspector, 86 view, 87 changeTestData 88 ); 89 90 info("Test autocompletion creating a new property"); 91 await runNewPropertyAutocompletionTest( 92 toolbox, 93 inspector, 94 view, 95 newAreaTestData 96 ); 97 98 info("Test autocompletion creating a new property"); 99 await runNewPropertyAutocompletionTest( 100 toolbox, 101 inspector, 102 view, 103 newRowTestData 104 ); 105 }); 106 107 async function runNewPropertyAutocompletionTest( 108 toolbox, 109 inspector, 110 view, 111 testData 112 ) { 113 info("Selecting the test node"); 114 await selectNode("#cell2", inspector); 115 116 info("Focusing the css property editable field"); 117 const ruleEditor = getRuleViewRuleEditor(view, 0); 118 const editor = await focusNewRuleViewProperty(ruleEditor); 119 120 info("Starting to test for css property completion"); 121 for (const data of testData) { 122 await testCompletion(data, editor, view); 123 } 124 } 125 126 async function runChangePropertyAutocompletionTest( 127 toolbox, 128 inspector, 129 view, 130 testData 131 ) { 132 info("Selecting the test node"); 133 await selectNode("#cell3", inspector); 134 135 const ruleEditor = getRuleViewRuleEditor(view, 1).rule; 136 const prop = ruleEditor.textProps[0]; 137 138 info("Focusing the css property editable value"); 139 const gridLineNamesUpdated = inspector.once("grid-line-names-updated"); 140 let editor = await focusEditableField(view, prop.editor.valueSpan); 141 await gridLineNamesUpdated; 142 143 info("Starting to test for css property completion"); 144 for (const data of testData) { 145 // Re-define the editor at each iteration, because the focus may have moved 146 // from property to value and back 147 editor = inplaceEditor(view.styleDocument.activeElement); 148 await testCompletion(data, editor, view); 149 } 150 } 151 152 async function testCompletion( 153 [key, modifiers, completion, flags], 154 editor, 155 view 156 ) { 157 const open = !!(flags & OPEN); 158 const selected = !!(flags & SELECTED); 159 const change = !!(flags & CHANGE); 160 const submitPropertyName = !!(flags & SUBMIT_PROPERTY_NAME); 161 162 info( 163 `Pressing key "${key}", expecting "${completion}", popup opened: ${open}, item selected: ${selected}` 164 ); 165 166 const promises = []; 167 168 if (change) { 169 // If the key triggers a ruleview-changed, wait for that event, it will 170 // always be the last to be triggered and tells us when the preview has 171 // been done. 172 promises.push(view.once("ruleview-changed")); 173 } else if (key !== "VK_RIGHT" && key !== "VK_BACK_SPACE") { 174 // Otherwise, expect an after-suggest event (except if the autocomplete gets dismissed). 175 promises.push(editor.once("after-suggest")); 176 } 177 178 // If the key submits the property name, the popup gets closed, the editor for the 179 // property value is created and the popup (with the grid line names) is opened. 180 if (submitPropertyName) { 181 promises.push( 182 // So we need to listen for the popup being closed… 183 editor.popup.once("popup-closed"), 184 // … and opened again 185 editor.popup.once("popup-opened"), 186 // and check that the grid line names were updated 187 view.inspector.once("grid-line-names-updated") 188 ); 189 } else if (editor.popup.isOpen !== open) { 190 // if the key does not submit the property name, we only want to wait for popup 191 // events if the current state of the popup is different from the one that is 192 // expected after 193 promises.push(editor.popup.once(open ? "popup-opened" : "popup-closed")); 194 } 195 196 info( 197 `Synthesizing key "${key}", modifiers: ${JSON.stringify(Object.keys(modifiers))}` 198 ); 199 200 EventUtils.synthesizeKey(key, modifiers, view.styleWindow); 201 202 // Flush the debounce for the preview text. 203 view.debounce.flush(); 204 205 // Wait for all the events 206 await Promise.all(promises); 207 208 // The key might have been a TAB or shift-TAB, in which case the editor will 209 // be a new one 210 editor = inplaceEditor(view.styleDocument.activeElement); 211 212 info("Checking the state"); 213 if (completion !== null) { 214 try { 215 await waitFor(() => editor.input.value === completion); 216 } catch (e) { 217 // catch the exception so we'll get a nicer failure in the assertion below 218 } 219 is(editor.input.value, completion, "Correct value is autocompleted"); 220 } 221 222 if (!open) { 223 ok(!(editor.popup && editor.popup.isOpen), "Popup is closed"); 224 } else { 225 ok(editor.popup.isOpen, "Popup is open"); 226 is(editor.popup.selectedIndex !== -1, selected, "An item is selected"); 227 } 228 }