michael@0: /* vim: set ft=javascript 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 that pseudoelements are displayed correctly in the rule view michael@0: michael@0: const TEST_URI = TEST_URL_ROOT + "doc_pseudoelement.html"; michael@0: michael@0: let test = asyncTest(function*() { michael@0: yield addTab(TEST_URI); michael@0: let {toolbox, inspector, view} = yield openRuleView(); michael@0: michael@0: yield testTopLeft(inspector, view); michael@0: yield testTopRight(inspector, view); michael@0: yield testBottomRight(inspector, view); michael@0: yield testBottomLeft(inspector, view); michael@0: yield testParagraph(inspector, view); michael@0: yield testBody(inspector, view); michael@0: }); michael@0: michael@0: function* testTopLeft(inspector, view) { michael@0: let { michael@0: rules, michael@0: element, michael@0: elementStyle michael@0: } = yield assertPseudoElementRulesNumbers("#topleft", inspector, view, { michael@0: elementRulesNb: 4, michael@0: afterRulesNb: 1, michael@0: beforeRulesNb: 2, michael@0: firstLineRulesNb: 0, michael@0: firstLetterRulesNb: 0, michael@0: selectionRulesNb: 0 michael@0: }); michael@0: michael@0: let gutters = assertGutters(view); michael@0: michael@0: // Make sure that clicking on the twisty hides pseudo elements michael@0: let expander = gutters[0].querySelector(".ruleview-expander"); michael@0: ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded"); michael@0: expander.click(); michael@0: ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by twisty"); michael@0: expander.click(); michael@0: ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded again"); michael@0: michael@0: // Make sure that dblclicking on the header container also toggles the pseudo elements michael@0: EventUtils.synthesizeMouseAtCenter(gutters[0], {clickCount: 2}, inspector.sidebar.getWindowForTab("ruleview")); michael@0: ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by dblclicking"); michael@0: michael@0: let defaultView = element.ownerDocument.defaultView; michael@0: let elementRule = rules.elementRules[0]; michael@0: let elementRuleView = [].filter.call(view.element.children, e => { michael@0: return e._ruleEditor && e._ruleEditor.rule === elementRule; michael@0: })[0]._ruleEditor; michael@0: michael@0: let elementAfterRule = rules.afterRules[0]; michael@0: let elementAfterRuleView = [].filter.call(view.element.children, (e) => { michael@0: return e._ruleEditor && e._ruleEditor.rule === elementAfterRule; michael@0: })[0]._ruleEditor; michael@0: michael@0: is michael@0: ( michael@0: convertTextPropsToString(elementAfterRule.textProps), michael@0: "background: none repeat scroll 0% 0% red; content: \" \"; position: absolute; " + michael@0: "border-radius: 50%; height: 32px; width: 32px; top: 50%; left: 50%; margin-top: -16px; margin-left: -16px", michael@0: "TopLeft after properties are correct" michael@0: ); michael@0: michael@0: let elementBeforeRule = rules.beforeRules[0]; michael@0: let elementBeforeRuleView = [].filter.call(view.element.children, (e) => { michael@0: return e._ruleEditor && e._ruleEditor.rule === elementBeforeRule; michael@0: })[0]._ruleEditor; michael@0: michael@0: is michael@0: ( michael@0: convertTextPropsToString(elementBeforeRule.textProps), michael@0: "top: 0px; left: 0px", michael@0: "TopLeft before properties are correct" michael@0: ); michael@0: michael@0: let firstProp = elementAfterRuleView.addProperty("background-color", "rgb(0, 255, 0)", ""); michael@0: let secondProp = elementAfterRuleView.addProperty("padding", "100px", ""); michael@0: michael@0: is (firstProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 2], michael@0: "First added property is on back of array"); michael@0: is (secondProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 1], michael@0: "Second added property is on back of array"); michael@0: michael@0: yield elementAfterRule._applyingModifications; michael@0: michael@0: is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), michael@0: "rgb(0, 255, 0)", "Added property should have been used."); michael@0: is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), michael@0: "100px", "Added property should have been used."); michael@0: is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), michael@0: "32px", "Added property should not apply to element"); michael@0: michael@0: secondProp.setEnabled(false); michael@0: yield elementAfterRule._applyingModifications; michael@0: michael@0: is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "0px", michael@0: "Disabled property should have been used."); michael@0: is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px", michael@0: "Added property should not apply to element"); michael@0: michael@0: secondProp.setEnabled(true); michael@0: yield elementAfterRule._applyingModifications; michael@0: michael@0: is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "100px", michael@0: "Enabled property should have been used."); michael@0: is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px", michael@0: "Added property should not apply to element"); michael@0: michael@0: let firstProp = elementRuleView.addProperty("background-color", "rgb(0, 0, 255)", ""); michael@0: yield elementRule._applyingModifications; michael@0: michael@0: is(defaultView.getComputedStyle(element).getPropertyValue("background-color"), "rgb(0, 0, 255)", michael@0: "Added property should have been used."); michael@0: is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), "rgb(0, 255, 0)", michael@0: "Added prop does not apply to pseudo"); michael@0: } michael@0: michael@0: function* testTopRight(inspector, view) { michael@0: let { michael@0: rules, michael@0: element, michael@0: elementStyle michael@0: } = yield assertPseudoElementRulesNumbers("#topright", inspector, view, { michael@0: elementRulesNb: 4, michael@0: afterRulesNb: 1, michael@0: beforeRulesNb: 2, michael@0: firstLineRulesNb: 0, michael@0: firstLetterRulesNb: 0, michael@0: selectionRulesNb: 0 michael@0: }); michael@0: michael@0: let gutters = assertGutters(view); michael@0: michael@0: let expander = gutters[0].querySelector(".ruleview-expander"); michael@0: ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements remain collapsed after switching element"); michael@0: expander.scrollIntoView(); michael@0: expander.click(); michael@0: ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are shown again after clicking twisty"); michael@0: } michael@0: michael@0: function* testBottomRight(inspector, view) { michael@0: yield assertPseudoElementRulesNumbers("#bottomright", inspector, view, { michael@0: elementRulesNb: 4, michael@0: afterRulesNb: 1, michael@0: beforeRulesNb: 3, michael@0: firstLineRulesNb: 0, michael@0: firstLetterRulesNb: 0, michael@0: selectionRulesNb: 0 michael@0: }); michael@0: } michael@0: michael@0: function* testBottomLeft(inspector, view) { michael@0: yield assertPseudoElementRulesNumbers("#bottomleft", inspector, view, { michael@0: elementRulesNb: 4, michael@0: afterRulesNb: 1, michael@0: beforeRulesNb: 2, michael@0: firstLineRulesNb: 0, michael@0: firstLetterRulesNb: 0, michael@0: selectionRulesNb: 0 michael@0: }); michael@0: } michael@0: michael@0: function* testParagraph(inspector, view) { michael@0: let { michael@0: rules, michael@0: element, michael@0: elementStyle michael@0: } = yield assertPseudoElementRulesNumbers("#bottomleft p", inspector, view, { michael@0: elementRulesNb: 3, michael@0: afterRulesNb: 0, michael@0: beforeRulesNb: 0, michael@0: firstLineRulesNb: 1, michael@0: firstLetterRulesNb: 1, michael@0: selectionRulesNb: 1 michael@0: }); michael@0: michael@0: let gutters = assertGutters(view); michael@0: michael@0: let elementFirstLineRule = rules.firstLineRules[0]; michael@0: let elementFirstLineRuleView = [].filter.call(view.element.children, (e) => { michael@0: return e._ruleEditor && e._ruleEditor.rule === elementFirstLineRule; michael@0: })[0]._ruleEditor; michael@0: michael@0: is michael@0: ( michael@0: convertTextPropsToString(elementFirstLineRule.textProps), michael@0: "background: none repeat scroll 0% 0% blue", michael@0: "Paragraph first-line properties are correct" michael@0: ); michael@0: michael@0: let elementFirstLetterRule = rules.firstLetterRules[0]; michael@0: let elementFirstLetterRuleView = [].filter.call(view.element.children, (e) => { michael@0: return e._ruleEditor && e._ruleEditor.rule === elementFirstLetterRule; michael@0: })[0]._ruleEditor; michael@0: michael@0: is michael@0: ( michael@0: convertTextPropsToString(elementFirstLetterRule.textProps), michael@0: "color: red; font-size: 130%", michael@0: "Paragraph first-letter properties are correct" michael@0: ); michael@0: michael@0: let elementSelectionRule = rules.selectionRules[0]; michael@0: let elementSelectionRuleView = [].filter.call(view.element.children, (e) => { michael@0: return e._ruleEditor && e._ruleEditor.rule === elementSelectionRule; michael@0: })[0]._ruleEditor; michael@0: michael@0: is michael@0: ( michael@0: convertTextPropsToString(elementSelectionRule.textProps), michael@0: "color: white; background: none repeat scroll 0% 0% black", michael@0: "Paragraph first-letter properties are correct" michael@0: ); michael@0: } michael@0: michael@0: function* testBody(inspector, view) { michael@0: let {element, elementStyle} = yield testNode("body", inspector, view); michael@0: michael@0: let gutters = view.element.querySelectorAll(".theme-gutter"); michael@0: is (gutters.length, 0, "There are no gutter headings"); michael@0: } michael@0: michael@0: function convertTextPropsToString(textProps) { michael@0: return textProps.map(t => t.name + ": " + t.value).join("; "); michael@0: } michael@0: michael@0: function* testNode(selector, inspector, view) { michael@0: let element = getNode(selector); michael@0: yield selectNode(element, inspector); michael@0: let elementStyle = view._elementStyle; michael@0: return {element: element, elementStyle: elementStyle}; michael@0: } michael@0: michael@0: function* assertPseudoElementRulesNumbers(selector, inspector, view, ruleNbs) { michael@0: let {element, elementStyle} = yield testNode(selector, inspector, view); michael@0: michael@0: let rules = { michael@0: elementRules: elementStyle.rules.filter(rule => !rule.pseudoElement), michael@0: afterRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":after"), michael@0: beforeRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":before"), michael@0: firstLineRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":first-line"), michael@0: firstLetterRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":first-letter"), michael@0: selectionRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":-moz-selection") michael@0: }; michael@0: michael@0: is(rules.elementRules.length, ruleNbs.elementRulesNb, selector + michael@0: " has the correct number of non pseudo element rules"); michael@0: is(rules.afterRules.length, ruleNbs.afterRulesNb, selector + michael@0: " has the correct number of :after rules"); michael@0: is(rules.beforeRules.length, ruleNbs.beforeRulesNb, selector + michael@0: " has the correct number of :before rules"); michael@0: is(rules.firstLineRules.length, ruleNbs.firstLineRulesNb, selector + michael@0: " has the correct number of :first-line rules"); michael@0: is(rules.firstLetterRules.length, ruleNbs.firstLetterRulesNb, selector + michael@0: " has the correct number of :first-letter rules"); michael@0: is(rules.selectionRules.length, ruleNbs.selectionRulesNb, selector + michael@0: " has the correct number of :selection rules"); michael@0: michael@0: return {rules: rules, element: element, elementStyle: elementStyle}; michael@0: } michael@0: michael@0: function assertGutters(view) { michael@0: let gutters = view.element.querySelectorAll(".theme-gutter"); michael@0: is (gutters.length, 3, "There are 3 gutter headings"); michael@0: is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct"); michael@0: is (gutters[1].textContent, "This Element", "Gutter heading is correct"); michael@0: is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct"); michael@0: return gutters; michael@0: }