michael@0: /* vim: set ts=2 et sw=2 tw=80: */ michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: "use strict"; michael@0: michael@0: // Test CSS state is correctly determined and the corresponding suggestions are michael@0: // displayed. i.e. CSS property suggestions are shown when cursor is like: michael@0: // ```style="di|"``` where | is the cursor; And CSS value suggestion is michael@0: // displayed when the cursor is like: ```style="display:n|"``` properly. No michael@0: // suggestions should ever appear when the attribute is not a style attribute. michael@0: // The correctness and cycling of the suggestions is covered in the ruleview michael@0: // tests. michael@0: michael@0: const TEST_URL = TEST_URL_ROOT + "doc_markup_edit.html"; michael@0: // test data format : michael@0: // [ michael@0: // what key to press, michael@0: // expected input box value after keypress, michael@0: // expected input.selectionStart, michael@0: // expected input.selectionEnd, michael@0: // is popup expected to be open ? michael@0: // ] michael@0: const TEST_DATA = [ michael@0: ['s', 's', 1, 1, false], michael@0: ['t', 'st', 2, 2, false], michael@0: ['y', 'sty', 3, 3, false], michael@0: ['l', 'styl', 4, 4, false], michael@0: ['e', 'style', 5, 5, false], michael@0: ['=', 'style=', 6, 6, false], michael@0: ['"', 'style="', 7, 7, false], michael@0: ['d', 'style="direction', 8, 16, true], michael@0: ['VK_DOWN', 'style="display', 8, 14, true], michael@0: ['VK_TAB', 'style="display', 14, 14, true], michael@0: ['VK_TAB', 'style="dominant-baseline', 24, 24, true], michael@0: ['VK_TAB', 'style="direction', 16, 16, true], michael@0: ['click_1', 'style="display', 14, 14, false], michael@0: [':', 'style="display:-moz-box', 15, 23, true], michael@0: ['n', 'style="display:none', 16, 19, false], michael@0: ['VK_BACK_SPACE', 'style="display:n', 16, 16, false], michael@0: ['VK_BACK_SPACE', 'style="display:', 15, 15, false], michael@0: [' ', 'style="display: -moz-box', 16, 24, true], michael@0: [' ', 'style="display: -moz-box', 17, 25, true], michael@0: ['i', 'style="display: inherit', 18, 24, true], michael@0: ['VK_RIGHT', 'style="display: inherit', 24, 24, false], michael@0: [';', 'style="display: inherit;', 25, 25, false], michael@0: [' ', 'style="display: inherit; ', 26, 26, false], michael@0: [' ', 'style="display: inherit; ', 27, 27, false], michael@0: ['VK_LEFT', 'style="display: inherit; ', 26, 26, false], michael@0: ['c', 'style="display: inherit; caption-side ', 27, 38, true], michael@0: ['o', 'style="display: inherit; color ', 28, 31, true], michael@0: ['VK_RIGHT', 'style="display: inherit; color ', 31, 31, false], michael@0: [' ', 'style="display: inherit; color ', 32, 32, false], michael@0: ['c', 'style="display: inherit; color c ', 33, 33, false], michael@0: ['VK_BACK_SPACE', 'style="display: inherit; color ', 32, 32, false], michael@0: [':', 'style="display: inherit; color :aliceblue ', 33, 42, true], michael@0: ['c', 'style="display: inherit; color :cadetblue ', 34, 42, true], michael@0: ['VK_DOWN', 'style="display: inherit; color :chartreuse ', 34, 43, true], michael@0: ['VK_RIGHT', 'style="display: inherit; color :chartreuse ', 43, 43, false], michael@0: [' ', 'style="display: inherit; color :chartreuse !important; ', 44, 55, true], michael@0: ['!', 'style="display: inherit; color :chartreuse !important; ', 45, 55, false], michael@0: ['VK_RIGHT', 'style="display: inherit; color :chartreuse !important; ', 55, 55, false], michael@0: ['VK_RETURN', 'style="display: inherit; color :chartreuse !important;"', -1, -1, false] michael@0: ]; michael@0: michael@0: let test = asyncTest(function*() { michael@0: info("Opening the inspector on the test URL"); michael@0: let {inspector} = yield addTab(TEST_URL).then(openInspector); michael@0: michael@0: yield inspector.markup.expandAll(); michael@0: michael@0: let node = getContainerForRawNode("#node14", inspector).editor; michael@0: let attr = node.newAttr; michael@0: attr.focus(); michael@0: EventUtils.sendKey("return", inspector.panelWin); michael@0: let editor = inplaceEditor(attr); michael@0: michael@0: for (let i = 0; i < TEST_DATA.length; i ++) { michael@0: yield enterData(i, editor, inspector); michael@0: checkData(i, editor, inspector); michael@0: } michael@0: michael@0: while (inspector.markup.undo.canUndo()) { michael@0: yield undoChange(inspector); michael@0: } michael@0: michael@0: yield inspector.once("inspector-updated"); michael@0: }); michael@0: michael@0: function enterData(index, editor, inspector) { michael@0: let [key] = TEST_DATA[index]; michael@0: info("Entering test data " + index + ": " + key + ", expecting: [" + TEST_DATA[index].slice(1) + "]"); michael@0: michael@0: let def = promise.defer(); michael@0: michael@0: if (/click_[0-9]/.test(key)) { michael@0: let nb = +key.split("_")[1]; michael@0: info("Clicking on item " + nb + " in the list"); michael@0: editor.once("after-suggest", () => { michael@0: executeSoon(def.resolve); michael@0: }); michael@0: editor.popup._list.childNodes[nb].click(); michael@0: editor.input.blur(); michael@0: return def.promise; michael@0: } michael@0: michael@0: if (/(down|left|right|back_space|return)/ig.test(key)) { michael@0: info("Adding event listener for down|left|right|back_space|return keys"); michael@0: editor.input.addEventListener("keypress", function onKeypress() { michael@0: if (editor.input) { michael@0: editor.input.removeEventListener("keypress", onKeypress); michael@0: } michael@0: executeSoon(def.resolve); michael@0: }); michael@0: } else { michael@0: editor.once("after-suggest", () => { michael@0: executeSoon(def.resolve); michael@0: }); michael@0: } michael@0: EventUtils.synthesizeKey(key, {}, inspector.panelWin); michael@0: michael@0: return def.promise; michael@0: } michael@0: michael@0: function checkData(index, editor, inspector) { michael@0: let [key, completion, selStart, selEnd, popupOpen] = TEST_DATA[index]; michael@0: info("Test data " + index + " entered. Checking state."); michael@0: michael@0: if (selEnd != -1) { michael@0: is(editor.input.value, completion, "Completed value is correct"); michael@0: is(editor.input.selectionStart, selStart, "Selection start position is correct"); michael@0: is(editor.input.selectionEnd, selEnd, "Selection end position is correct"); michael@0: if (popupOpen) { michael@0: ok(editor.popup.isOpen, "Popup is open"); michael@0: } else { michael@0: ok(editor.popup._panel.state != "open" && editor.popup._panel.state != "showing", michael@0: "Popup is closed"); michael@0: } michael@0: } else { michael@0: let editor = getContainerForRawNode("#node14", inspector).editor; michael@0: let attr = editor.attrs["style"].querySelector(".editable"); michael@0: is(attr.textContent, completion, "Correct value is persisted after pressing Enter"); michael@0: } michael@0: }