|
1 /* vim: set ts=2 et sw=2 tw=80: */ |
|
2 /* Any copyright is dedicated to the Public Domain. |
|
3 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
4 |
|
5 "use strict"; |
|
6 |
|
7 // Test CSS state is correctly determined and the corresponding suggestions are |
|
8 // displayed. i.e. CSS property suggestions are shown when cursor is like: |
|
9 // ```style="di|"``` where | is the cursor; And CSS value suggestion is |
|
10 // displayed when the cursor is like: ```style="display:n|"``` properly. No |
|
11 // suggestions should ever appear when the attribute is not a style attribute. |
|
12 // The correctness and cycling of the suggestions is covered in the ruleview |
|
13 // tests. |
|
14 |
|
15 const TEST_URL = TEST_URL_ROOT + "doc_markup_edit.html"; |
|
16 // test data format : |
|
17 // [ |
|
18 // what key to press, |
|
19 // expected input box value after keypress, |
|
20 // expected input.selectionStart, |
|
21 // expected input.selectionEnd, |
|
22 // is popup expected to be open ? |
|
23 // ] |
|
24 const TEST_DATA = [ |
|
25 ['s', 's', 1, 1, false], |
|
26 ['t', 'st', 2, 2, false], |
|
27 ['y', 'sty', 3, 3, false], |
|
28 ['l', 'styl', 4, 4, false], |
|
29 ['e', 'style', 5, 5, false], |
|
30 ['=', 'style=', 6, 6, false], |
|
31 ['"', 'style="', 7, 7, false], |
|
32 ['d', 'style="direction', 8, 16, true], |
|
33 ['VK_DOWN', 'style="display', 8, 14, true], |
|
34 ['VK_TAB', 'style="display', 14, 14, true], |
|
35 ['VK_TAB', 'style="dominant-baseline', 24, 24, true], |
|
36 ['VK_TAB', 'style="direction', 16, 16, true], |
|
37 ['click_1', 'style="display', 14, 14, false], |
|
38 [':', 'style="display:-moz-box', 15, 23, true], |
|
39 ['n', 'style="display:none', 16, 19, false], |
|
40 ['VK_BACK_SPACE', 'style="display:n', 16, 16, false], |
|
41 ['VK_BACK_SPACE', 'style="display:', 15, 15, false], |
|
42 [' ', 'style="display: -moz-box', 16, 24, true], |
|
43 [' ', 'style="display: -moz-box', 17, 25, true], |
|
44 ['i', 'style="display: inherit', 18, 24, true], |
|
45 ['VK_RIGHT', 'style="display: inherit', 24, 24, false], |
|
46 [';', 'style="display: inherit;', 25, 25, false], |
|
47 [' ', 'style="display: inherit; ', 26, 26, false], |
|
48 [' ', 'style="display: inherit; ', 27, 27, false], |
|
49 ['VK_LEFT', 'style="display: inherit; ', 26, 26, false], |
|
50 ['c', 'style="display: inherit; caption-side ', 27, 38, true], |
|
51 ['o', 'style="display: inherit; color ', 28, 31, true], |
|
52 ['VK_RIGHT', 'style="display: inherit; color ', 31, 31, false], |
|
53 [' ', 'style="display: inherit; color ', 32, 32, false], |
|
54 ['c', 'style="display: inherit; color c ', 33, 33, false], |
|
55 ['VK_BACK_SPACE', 'style="display: inherit; color ', 32, 32, false], |
|
56 [':', 'style="display: inherit; color :aliceblue ', 33, 42, true], |
|
57 ['c', 'style="display: inherit; color :cadetblue ', 34, 42, true], |
|
58 ['VK_DOWN', 'style="display: inherit; color :chartreuse ', 34, 43, true], |
|
59 ['VK_RIGHT', 'style="display: inherit; color :chartreuse ', 43, 43, false], |
|
60 [' ', 'style="display: inherit; color :chartreuse !important; ', 44, 55, true], |
|
61 ['!', 'style="display: inherit; color :chartreuse !important; ', 45, 55, false], |
|
62 ['VK_RIGHT', 'style="display: inherit; color :chartreuse !important; ', 55, 55, false], |
|
63 ['VK_RETURN', 'style="display: inherit; color :chartreuse !important;"', -1, -1, false] |
|
64 ]; |
|
65 |
|
66 let test = asyncTest(function*() { |
|
67 info("Opening the inspector on the test URL"); |
|
68 let {inspector} = yield addTab(TEST_URL).then(openInspector); |
|
69 |
|
70 yield inspector.markup.expandAll(); |
|
71 |
|
72 let node = getContainerForRawNode("#node14", inspector).editor; |
|
73 let attr = node.newAttr; |
|
74 attr.focus(); |
|
75 EventUtils.sendKey("return", inspector.panelWin); |
|
76 let editor = inplaceEditor(attr); |
|
77 |
|
78 for (let i = 0; i < TEST_DATA.length; i ++) { |
|
79 yield enterData(i, editor, inspector); |
|
80 checkData(i, editor, inspector); |
|
81 } |
|
82 |
|
83 while (inspector.markup.undo.canUndo()) { |
|
84 yield undoChange(inspector); |
|
85 } |
|
86 |
|
87 yield inspector.once("inspector-updated"); |
|
88 }); |
|
89 |
|
90 function enterData(index, editor, inspector) { |
|
91 let [key] = TEST_DATA[index]; |
|
92 info("Entering test data " + index + ": " + key + ", expecting: [" + TEST_DATA[index].slice(1) + "]"); |
|
93 |
|
94 let def = promise.defer(); |
|
95 |
|
96 if (/click_[0-9]/.test(key)) { |
|
97 let nb = +key.split("_")[1]; |
|
98 info("Clicking on item " + nb + " in the list"); |
|
99 editor.once("after-suggest", () => { |
|
100 executeSoon(def.resolve); |
|
101 }); |
|
102 editor.popup._list.childNodes[nb].click(); |
|
103 editor.input.blur(); |
|
104 return def.promise; |
|
105 } |
|
106 |
|
107 if (/(down|left|right|back_space|return)/ig.test(key)) { |
|
108 info("Adding event listener for down|left|right|back_space|return keys"); |
|
109 editor.input.addEventListener("keypress", function onKeypress() { |
|
110 if (editor.input) { |
|
111 editor.input.removeEventListener("keypress", onKeypress); |
|
112 } |
|
113 executeSoon(def.resolve); |
|
114 }); |
|
115 } else { |
|
116 editor.once("after-suggest", () => { |
|
117 executeSoon(def.resolve); |
|
118 }); |
|
119 } |
|
120 EventUtils.synthesizeKey(key, {}, inspector.panelWin); |
|
121 |
|
122 return def.promise; |
|
123 } |
|
124 |
|
125 function checkData(index, editor, inspector) { |
|
126 let [key, completion, selStart, selEnd, popupOpen] = TEST_DATA[index]; |
|
127 info("Test data " + index + " entered. Checking state."); |
|
128 |
|
129 if (selEnd != -1) { |
|
130 is(editor.input.value, completion, "Completed value is correct"); |
|
131 is(editor.input.selectionStart, selStart, "Selection start position is correct"); |
|
132 is(editor.input.selectionEnd, selEnd, "Selection end position is correct"); |
|
133 if (popupOpen) { |
|
134 ok(editor.popup.isOpen, "Popup is open"); |
|
135 } else { |
|
136 ok(editor.popup._panel.state != "open" && editor.popup._panel.state != "showing", |
|
137 "Popup is closed"); |
|
138 } |
|
139 } else { |
|
140 let editor = getContainerForRawNode("#node14", inspector).editor; |
|
141 let attr = editor.attrs["style"].querySelector(".editable"); |
|
142 is(attr.textContent, completion, "Correct value is persisted after pressing Enter"); |
|
143 } |
|
144 } |