Web Inspector: Add PrettyPrinter CSS tests
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 4 Oct 2014 22:11:57 +0000 (22:11 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 4 Oct 2014 22:11:57 +0000 (22:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=134005

Patch by Joseph Pecoraro <pecoraro@apple.com> on 2014-10-04
Reviewed by Timothy Hatcher.

Add CSS pretty printing tests. Improve pretty printing of calc()
expressions and media-queries with whitespace around operators
and keywords. Also fix the debug output in the tool for CSS.

* Tools/PrettyPrinting/CodeMirrorFormatters.js:
* Tools/PrettyPrinting/FormatterContentBuilder.js:
(FormatterContentBuilder.prototype._appendIndent):
* Tools/PrettyPrinting/FormatterDebug.js:
(.debugToken):
(Formatter.prototype.debug):
* Tools/PrettyPrinting/css-tests/basic-expected.css: Added.
* Tools/PrettyPrinting/css-tests/basic.css: Added.
* Tools/PrettyPrinting/css-tests/calc-expected.css: Added.
* Tools/PrettyPrinting/css-tests/calc.css: Added.
* Tools/PrettyPrinting/css-tests/media-query-expected.css: Added.
* Tools/PrettyPrinting/css-tests/media-query.css: Added.
* Tools/PrettyPrinting/css-tests/selectors-expected.css: Added.
* Tools/PrettyPrinting/css-tests/selectors.css: Added.
* Tools/PrettyPrinting/index.html:
* UserInterface/Views/CodeMirrorFormatters.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@174323 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Tools/PrettyPrinting/CodeMirrorFormatters.js
Source/WebInspectorUI/Tools/PrettyPrinting/FormatterContentBuilder.js
Source/WebInspectorUI/Tools/PrettyPrinting/FormatterDebug.js
Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/basic-expected.css [new file with mode: 0644]
Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/basic.css [new file with mode: 0644]
Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/calc-expected.css [new file with mode: 0644]
Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/calc.css [new file with mode: 0644]
Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/media-query-expected.css [new file with mode: 0644]
Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/media-query.css [new file with mode: 0644]
Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/selectors-expected.css [new file with mode: 0644]
Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/selectors.css [new file with mode: 0644]
Source/WebInspectorUI/Tools/PrettyPrinting/index.html
Source/WebInspectorUI/UserInterface/Views/CodeMirrorFormatters.js

index b225079013eb58b3c37c060f7ecb47def5c7c468..a6c9d0ede37d00a2093fd282bcc6612ea526a892 100644 (file)
@@ -1,3 +1,31 @@
+2014-10-04  Joseph Pecoraro  <pecoraro@apple.com>
+
+        Web Inspector: Add PrettyPrinter CSS tests
+        https://bugs.webkit.org/show_bug.cgi?id=134005
+
+        Reviewed by Timothy Hatcher.
+
+        Add CSS pretty printing tests. Improve pretty printing of calc()
+        expressions and media-queries with whitespace around operators
+        and keywords. Also fix the debug output in the tool for CSS.
+
+        * Tools/PrettyPrinting/CodeMirrorFormatters.js:
+        * Tools/PrettyPrinting/FormatterContentBuilder.js:
+        (FormatterContentBuilder.prototype._appendIndent):
+        * Tools/PrettyPrinting/FormatterDebug.js:
+        (.debugToken):
+        (Formatter.prototype.debug):
+        * Tools/PrettyPrinting/css-tests/basic-expected.css: Added.
+        * Tools/PrettyPrinting/css-tests/basic.css: Added.
+        * Tools/PrettyPrinting/css-tests/calc-expected.css: Added.
+        * Tools/PrettyPrinting/css-tests/calc.css: Added.
+        * Tools/PrettyPrinting/css-tests/media-query-expected.css: Added.
+        * Tools/PrettyPrinting/css-tests/media-query.css: Added.
+        * Tools/PrettyPrinting/css-tests/selectors-expected.css: Added.
+        * Tools/PrettyPrinting/css-tests/selectors.css: Added.
+        * Tools/PrettyPrinting/index.html:
+        * UserInterface/Views/CodeMirrorFormatters.js:
+
 2014-10-04  Brian J. Burg  <burg@cs.washington.edu>
 
         Unreviewed, rolling out r174319.
index a4075d40adfdd8edf0a7f1db5b76b4d16bc19002..758d1bccf23bebfabf11cbf93d25f7547bd07bda 100644 (file)
@@ -300,7 +300,7 @@ CodeMirror.extendMode("css", {
         if (!token) {
             if (content === "{")
                 return true;
-            return false;
+            return ">+~-*/".indexOf(content) >= 0; // calc() expression or child/sibling selectors
         }
 
         if (isComment)
@@ -322,12 +322,17 @@ CodeMirror.extendMode("css", {
                 return true;
             if (lastContent === ":") // Space in "prop: value" but not in a selectors "a:link" or "div::after" or media queries "(max-device-width:480px)".
                 return state.state === "prop";
-            return false;
+            if (lastContent === ")" && (content !== ")" && content !== ",")) // Space in "not(foo)and" but not at the end of "not(not(foo))"
+                return state.state === "media" || state.state === "media_parens";
+            return ">+~-*/".indexOf(lastContent) >= 0; // calc() expression or child/sibling selectors
         }
 
         if (/\bcomment\b/.test(lastToken))
             return true;
 
+        if (/\bkeyword\b/.test(lastToken)) // media-query keywords
+            return state.state === "media" || state.state === "media_parens";
+
         return false;
     },
 
index f532d5c2110d75ed7d268657ec1aa06ff8449d4a..3c36a2bb3f3844e837c6b0a86ff8a8c8e5e300b4 100644 (file)
@@ -196,7 +196,7 @@ FormatterContentBuilder.prototype = {
         const maxCacheIndent = 20;
         var max = Math.min(this._indent, maxCacheIndent);
         for (var i = this._indentCache.length; i <= max; ++i)
-            this._indentCache[i] = this._indentCache[i-1] + this._indentString;
+            this._indentCache[i] = this._indentCache[i - 1] + this._indentString;
 
         // Append indents as needed.
         var indent = this._indent;
index 7e803a0e83e3392baaffe193fea4c9fe2b29b20a..aab35b9992d59f07c05eacda23a3b0a45326e7d4 100644 (file)
@@ -23,11 +23,13 @@ Formatter.prototype.debug = function(from, to)
 
         // Language Specific Info
         if (state.lexical) {
+            // JavaScript
             debug += "Lexical: " + pad(String(state.lexical.type), 10); // JavaScript
             debug += "Prev: " + pad(String(state.lexical.prev ? state.lexical.prev.type : state.lexical.prev), 10, !state.lexical.prev);
+        } else if (state.state) {
+            // CSS
+            debug += "State: " + pad(String(state.state), 16);
         }
-        else if (state.stack)
-            debug += "Stack: " + pad(String(state.stack[state.stack.length-1]), 16); // CSS
 
         // String
         debug += "Current: '" + stream.current() + "'\n";
diff --git a/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/basic-expected.css b/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/basic-expected.css
new file mode 100644 (file)
index 0000000..e549f9f
--- /dev/null
@@ -0,0 +1,95 @@
+/* RESET */
+html, body, div, ul, ol, li, dl, dt, dd, h1, h2, h3, h4, h5, h6,
+pre, form, p, blockquote, fieldset, input, abbr, article, aside, command,
+details, figcaption, figure, footer, header, hgroup, mark, meter, nav,
+output, progress, section, summary, time {
+    margin: 0;
+    padding: 0;
+}
+
+h1, h2, h3, h4, h5, h6, pre, code, address, caption, cite, code, em, strong,
+th, figcaption {
+    font-size: 1em;
+    font-weight: normal;
+    font-style: normal;
+}
+
+fieldset, iframe {
+    border: none
+}
+
+table {
+    border-collapse: collapse;
+    border-spacing: 0
+}
+
+article, aside, footer, header, hgroup, nav, section, figure, figcaption {
+    display: block;
+}
+
+/* FIXME: extra whitespace */
+caption , th {
+    text-align: left;
+}
+
+/* IMPORTANT */
+/* FIXME: whitespace between "!" and "important" can be improved */
+body {
+    color: red !important;
+}
+
+body {
+    color: red !important;
+}
+
+body {
+    color: red ! important;
+}
+
+/* INLINE COMMENT */
+body {
+    color: red; /* blue */
+}
+
+/* URLS */
+.myimage {
+    background-image: url(http://example.com/image.png), url(two.png)
+}
+
+.myimage {
+    background-image: url("http://example.com/image.png"), url("two.png")
+}
+
+/* PREFIXED SELECTORS AND PROPERTIES */
+.foo -webkit-any(a, b, c) {
+    -webkit-transition: all;
+    color: red
+}
+
+/* PSEUDO SELECTORS */
+a:link, a:visited {
+    color: black
+}
+
+/* PSEUDO ELEMENTS */
+p::before, p::after {
+    content: "test";
+}
+
+/* RGB, HSL */
+body {
+    color: rgb(1, 1, 1);
+    color: rgba(100, 0, 255, 0.5);
+    color: hsl(120, 100%, 50%);
+    color: hsla(120, 60%, 70%, 0.3);
+}
+
+/*
+ * This is a multi-line comment.
+ * - with indentation
+ * - and is generally awesome.
+ */
+body {
+    color: red
+}
+
diff --git a/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/basic.css b/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/basic.css
new file mode 100644 (file)
index 0000000..0939f48
--- /dev/null
@@ -0,0 +1,41 @@
+/* RESET */
+html,body,div,ul,ol,li,dl,dt,dd,h1,h2,h3,h4,h5,h6,pre,form,p,blockquote,fieldset,input,abbr,article,aside,command,details,figcaption,figure,footer,header,hgroup,mark,meter,nav,output,progress,section,summary,time { margin: 0; padding: 0; }
+h1,h2,h3,h4,h5,h6,pre,code,address,caption,cite,code,em,strong,th,figcaption { font-size: 1em; font-weight: normal; font-style: normal; }
+fieldset,iframe{border:none}
+table{border-collapse:collapse;border-spacing:0}
+article,aside,footer,header,hgroup,nav,section,figure,figcaption{display: block;}
+
+/* FIXME: extra whitespace */
+caption  ,   th { text-align: left; }
+
+/* IMPORTANT */
+/* FIXME: whitespace between "!" and "important" can be improved */
+body{color:red!important;}
+body{color:red !important;}
+body{color:red ! important;}
+
+/* INLINE COMMENT */
+body{color:red;/* blue */}
+
+/* URLS */
+.myimage{background-image:url(http://example.com/image.png),url(two.png)}
+.myimage{background-image:url("http://example.com/image.png"),url("two.png")}
+
+/* PREFIXED SELECTORS AND PROPERTIES */
+.foo -webkit-any(a,b,c){-webkit-transition:all;color:red}
+
+/* PSEUDO SELECTORS */
+a:link,a:visited{color:black}
+
+/* PSEUDO ELEMENTS */
+p::before,p::after{content:"test";}
+
+/* RGB, HSL */
+body{color:rgb(1,1,1);color:rgba(100,0,255,0.5);color:hsl(120,100%,50%);color:hsla(120,60%,70%,0.3);}
+
+/*
+ * This is a multi-line comment.
+ * - with indentation
+ * - and is generally awesome.
+ */
+body{color:red}
diff --git a/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/calc-expected.css b/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/calc-expected.css
new file mode 100644 (file)
index 0000000..34de338
--- /dev/null
@@ -0,0 +1,22 @@
+/* CALC EXPRESSIONS */
+/* FIXME: negative numbers can be improved */
+div {
+    width: -webkit-calc(100% + 80px + 1em);
+}
+
+div {
+    width: -webkit-calc(100% / 6);
+}
+
+div {
+    width: -webkit-calc(10% * 6);
+}
+
+div {
+    width: calc(-960px + 75%);
+}
+
+div {
+    width: calc(100vw-50vw);
+}
+
diff --git a/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/calc.css b/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/calc.css
new file mode 100644 (file)
index 0000000..25d68d1
--- /dev/null
@@ -0,0 +1,7 @@
+/* CALC EXPRESSIONS */
+/* FIXME: negative numbers can be improved */
+div{width:-webkit-calc(100%+80px+1em);}
+div{width:-webkit-calc(100%/6);}
+div{width:-webkit-calc(10%*6);}
+div{width:calc(-960px+75%);}
+div{width:calc(100vw-50vw);}
diff --git a/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/media-query-expected.css b/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/media-query-expected.css
new file mode 100644 (file)
index 0000000..2ad229b
--- /dev/null
@@ -0,0 +1,35 @@
+/* MEDIA QUERY INDENTATION */
+@media print {
+    body, #main, #content {
+        color: #000 !important;
+    }
+
+    a, a:link, a:visited {
+        color: #000 !important;
+        text-decoration: none !important;
+    }
+
+    #tabs, #globalheader, #globalfooter, #directorynav, .noprint, .hide {
+        display: none !important;
+    }
+
+    #main a.pdf, #main a.html, #main a.qt, #main a.ical, #main a.dl, #main a.dmg,
+    #main a.zip, #main a.keynote, #main a.audio {
+        padding-left: 0;
+        background-image: none;
+    }
+}
+
+/* MEDIA QUERY */
+@media screen and (max-device-width:480px) {
+    html {
+        -webkit-text-size-adjust: none;
+    }
+}
+
+@media not ((screen) and (print)), (print) {
+    body {
+        color: red
+    }
+}
+
diff --git a/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/media-query.css b/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/media-query.css
new file mode 100644 (file)
index 0000000..b86bcff
--- /dev/null
@@ -0,0 +1,6 @@
+/* MEDIA QUERY INDENTATION */
+@media print{body,#main,#content{color:#000!important;}a,a:link,a:visited{color:#000!important;text-decoration:none!important;}#tabs,#globalheader,#globalfooter,#directorynav,.noprint,.hide{display:none!important;}#main a.pdf,#main a.html,#main a.qt,#main a.ical,#main a.dl,#main a.dmg,#main a.zip,#main a.keynote,#main a.audio{padding-left:0;background-image:none;}}
+
+/* MEDIA QUERY */
+@media screen and(max-device-width:480px){html{-webkit-text-size-adjust:none;}}
+@media not((screen)and(print)),(print){body{color:red}}
diff --git a/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/selectors-expected.css b/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/selectors-expected.css
new file mode 100644 (file)
index 0000000..2e007f9
--- /dev/null
@@ -0,0 +1,8 @@
+/* SHORT SELECTOR, EMPTY CONTENT */
+a {}
+
+/* COMPLEX SELECTOR */
+div div > div#id.foo.bar:hover .something > .child ~ .sibling + .sibling::after {
+    color: red;
+}
+
diff --git a/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/selectors.css b/Source/WebInspectorUI/Tools/PrettyPrinting/css-tests/selectors.css
new file mode 100644 (file)
index 0000000..5a3ef7c
--- /dev/null
@@ -0,0 +1,5 @@
+/* SHORT SELECTOR, EMPTY CONTENT */
+a{}
+
+/* COMPLEX SELECTOR */
+div div>div#id.foo.bar:hover .something>.child~.sibling+.sibling::after{color:red;}
index 4002852354f680c431e65f711f4809882ede4be8..d4e202076e34775b3f6daa0cf86c16bb3f5a5285 100644 (file)
     // Button helpers.
     var buttons = ["mode", "populate", "run-tests", "clear", "select-output", "run-again"];
     function disableButtons() {
-        console.log("disableButtons");
         buttons.forEach(function(id) {
             document.getElementById(id).disabled = true;
         });
     }
     function enableButtons() {
-        console.log("enableButtons");
         buttons.forEach(function(id) {
             document.getElementById(id).disabled = false;
         });
         ]);
     }
     function runCSSTests(callback) {
-        _runTests(callback, []);
+        _runTests(callback, [
+            "css-tests/basic.css",
+            "css-tests/calc.css",
+            "css-tests/media-query.css",
+            "css-tests/selectors.css",
+        ]);
     }
     function _runTests(callback, manifest) {
         var index = -1;
 
             // Load test and expected results.
             var test = manifest[index];
-            var expected = test.replace(/\.js$/, "-expected.js");
+            var expected = test.replace(/\.([^\.]+)$/, "-expected.$1");
             var xhr1 = new XMLHttpRequest;
             xhr1.open("GET", test, false);
             xhr1.send();
             // Compare results.
             var pass = builder.formattedContent === expectedData;
             results.push("/* " + (pass ? "PASS" : "FAIL") + ": " + test + " */");
+
+            // Output failures to console.
+            if (!pass) {
+                console.log("Test", test, "Expected", expected);
+                console.log("Formatted Output", builder.formattedContent.length);
+                console.log(builder.formattedContent);
+                console.log("Expected Output", expectedData.length);
+                console.log(expectedData);
+            }
+
             runNextTest();
         }
 
index a4075d40adfdd8edf0a7f1db5b76b4d16bc19002..758d1bccf23bebfabf11cbf93d25f7547bd07bda 100644 (file)
@@ -300,7 +300,7 @@ CodeMirror.extendMode("css", {
         if (!token) {
             if (content === "{")
                 return true;
-            return false;
+            return ">+~-*/".indexOf(content) >= 0; // calc() expression or child/sibling selectors
         }
 
         if (isComment)
@@ -322,12 +322,17 @@ CodeMirror.extendMode("css", {
                 return true;
             if (lastContent === ":") // Space in "prop: value" but not in a selectors "a:link" or "div::after" or media queries "(max-device-width:480px)".
                 return state.state === "prop";
-            return false;
+            if (lastContent === ")" && (content !== ")" && content !== ",")) // Space in "not(foo)and" but not at the end of "not(not(foo))"
+                return state.state === "media" || state.state === "media_parens";
+            return ">+~-*/".indexOf(lastContent) >= 0; // calc() expression or child/sibling selectors
         }
 
         if (/\bcomment\b/.test(lastToken))
             return true;
 
+        if (/\bkeyword\b/.test(lastToken)) // media-query keywords
+            return state.state === "media" || state.state === "media_parens";
+
         return false;
     },