Title: [246178] trunk
Revision
246178
Author
[email protected]
Date
2019-06-06 16:35:12 -0700 (Thu, 06 Jun 2019)

Log Message

Web Inspector: Formatter: pretty-print CSS using a Worker
https://bugs.webkit.org/show_bug.cgi?id=197829
<rdar://problem/36891532>

Reviewed by Timothy Hatcher.

Source/WebInspectorUI:

* UserInterface/Proxies/FormatterWorkerProxy.js:
(WI.FormatterWorkerProxy.prototype.formatCSS): Added.
* UserInterface/Workers/Formatter/FormatterWorker.js:
(FormatterWorker.prototype.formatCSS): Added.
* UserInterface/Workers/Formatter/CSSFormatter.js: Added.
(CSSFormatter):
(CSSFormatter.prototype.get success):
(CSSFormatter.prototype.get formattedText):
(CSSFormatter.prototype.get sourceMapData):
(CSSFormatter.prototype._format):

* UserInterface/Workers/Formatter/FormatterContentBuilder.js:
(FormatterContentBuilder.prototype.get currentLine): Added.

* UserInterface/Views/TextEditor.js:
(WI.TextEditor.prototype._canUseFormatterWorker):
(WI.TextEditor.prototype._startWorkerPrettyPrint):

* .eslintrc:

LayoutTests:

* inspector/formatting/formatting-css.html: Added.
* inspector/formatting/formatting-css-expected.txt: Added.
* inspector/formatting/resources/css-tests/basic-expected.css: Added.
* inspector/formatting/resources/css-tests/basic.css: Added.
* inspector/formatting/resources/css-tests/gradient-expected.css: Added.
* inspector/formatting/resources/css-tests/gradient.css: Added.
* inspector/formatting/resources/css-tests/keyframes-expected.css: Added.
* inspector/formatting/resources/css-tests/keyframes.css: Added.
* inspector/formatting/resources/css-tests/media-query-expected.css: Added.
* inspector/formatting/resources/css-tests/media-query.css: Added.
* inspector/formatting/resources/css-tests/selectors-expected.css: Added.
* inspector/formatting/resources/css-tests/selectors.css: Added.
* inspector/formatting/resources/css-tests/wrapping-expected.css: Added.
* inspector/formatting/resources/css-tests/wrapping.css: Added.
* inspector/formatting/resources/utilities.js:
(TestPage.registerInitializer.runFormattingTest):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (246177 => 246178)


--- trunk/LayoutTests/ChangeLog	2019-06-06 23:31:40 UTC (rev 246177)
+++ trunk/LayoutTests/ChangeLog	2019-06-06 23:35:12 UTC (rev 246178)
@@ -1,3 +1,28 @@
+2019-06-06  Devin Rousso  <[email protected]>
+
+        Web Inspector: Formatter: pretty-print CSS using a Worker
+        https://bugs.webkit.org/show_bug.cgi?id=197829
+        <rdar://problem/36891532>
+
+        Reviewed by Timothy Hatcher.
+
+        * inspector/formatting/formatting-css.html: Added.
+        * inspector/formatting/formatting-css-expected.txt: Added.
+        * inspector/formatting/resources/css-tests/basic-expected.css: Added.
+        * inspector/formatting/resources/css-tests/basic.css: Added.
+        * inspector/formatting/resources/css-tests/gradient-expected.css: Added.
+        * inspector/formatting/resources/css-tests/gradient.css: Added.
+        * inspector/formatting/resources/css-tests/keyframes-expected.css: Added.
+        * inspector/formatting/resources/css-tests/keyframes.css: Added.
+        * inspector/formatting/resources/css-tests/media-query-expected.css: Added.
+        * inspector/formatting/resources/css-tests/media-query.css: Added.
+        * inspector/formatting/resources/css-tests/selectors-expected.css: Added.
+        * inspector/formatting/resources/css-tests/selectors.css: Added.
+        * inspector/formatting/resources/css-tests/wrapping-expected.css: Added.
+        * inspector/formatting/resources/css-tests/wrapping.css: Added.
+        * inspector/formatting/resources/utilities.js:
+        (TestPage.registerInitializer.runFormattingTest):
+
 2019-06-06  Youenn Fablet  <[email protected]>
 
         REGRESSION (r243270) [ iOS Sim Release ] Layout Test imported/w3c/web-platform-tests/IndexedDB/keypath-special-identifiers.htm is a flaky failure

Added: trunk/LayoutTests/inspector/formatting/formatting-css-expected.txt (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/formatting-css-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/formatting-css-expected.txt	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1,22 @@
+Test CSS formatting.
+
+
+== Running test suite: CSSFormatter
+-- Running test case: CSSFormatter.basic.css
+PASS
+
+-- Running test case: CSSFormatter.gradient.css
+PASS
+
+-- Running test case: CSSFormatter.keyframes.css
+PASS
+
+-- Running test case: CSSFormatter.media-query.css
+PASS
+
+-- Running test case: CSSFormatter.selectors.css
+PASS
+
+-- Running test case: CSSFormatter.wrapping.css
+PASS
+

Added: trunk/LayoutTests/inspector/formatting/formatting-css.html (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/formatting-css.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/formatting-css.html	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+<script>
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("CSSFormatter");
+
+    addFormattingTests(suite, "text/css", [
+        "resources/css-tests/basic.css",
+        "resources/css-tests/gradient.css",
+        "resources/css-tests/keyframes.css",
+        "resources/css-tests/media-query.css",
+        "resources/css-tests/selectors.css",
+        "resources/css-tests/wrapping.css",
+    ]);
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Test CSS formatting.</p>
+</body>
+</html>

Added: trunk/LayoutTests/inspector/formatting/resources/css-tests/basic-expected.css (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/css-tests/basic-expected.css	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/css-tests/basic-expected.css	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1,90 @@
+/* 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;
+}
+
+caption, th {
+    text-align: left;
+}
+
+/* IMPORTANT */
+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 :matches(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
+}
+

Added: trunk/LayoutTests/inspector/formatting/resources/css-tests/basic.css (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/css-tests/basic.css	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/css-tests/basic.css	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1,39 @@
+/* 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;}
+
+caption  ,   th { text-align: left; }
+
+/* IMPORTANT */
+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 :matches(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}

Added: trunk/LayoutTests/inspector/formatting/resources/css-tests/gradient-expected.css (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/css-tests/gradient-expected.css	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/css-tests/gradient-expected.css	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1,9 @@
+.dot-nav:nth-child(1n) li a.active {
+    top: 0;
+    background: #08c;
+    background: -webkit-gradient(linear, lefttop, leftbottom, color-stop(0%, rgb(126, 198, 234)), color-stop(24%, rgb(70, 179, 234)), color-stop(100%, rgb(3, 135, 201)));
+    background: -webkit-linear-gradient(top, rgb(126, 198, 234) 0%, rgb(70, 179, 234) 45%, rgb(3, 135, 201) 100%);
+    background: -moz-linear-gradient(top, rgb(126, 198, 234) 0%, rgb(70, 179, 234) 45%, rgb(3, 135, 201) 100%);
+    background: linear-gradient(top, rgb(126, 198, 234) 0%, rgb(70, 179, 234) 45%, rgb(3, 135, 201) 100%);
+}
+

Added: trunk/LayoutTests/inspector/formatting/resources/css-tests/gradient.css (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/css-tests/gradient.css	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/css-tests/gradient.css	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1,7 @@
+.dot-nav:nth-child(1n) li a.active {
+    top:0;background:#08c;
+	background:-webkit-gradient(linear,lefttop,leftbottom,color-stop(0%,rgb(126,198,234)),color-stop(24%,rgb(70,179,234)),color-stop(100%,rgb(3,135,201)));
+	background:-webkit-linear-gradient(top,rgb(126,198,234)0%,rgb(70,179,234)45%,rgb(3,135,201)100%);
+	background:   -moz-linear-gradient(top,rgb(126,198,234)0%,rgb(70,179,234)45%,rgb(3,135,201)100%);
+	background:        linear-gradient(top,rgb(126,198,234)0%,rgb(70,179,234)45%,rgb(3,135,201)100%);
+}

Added: trunk/LayoutTests/inspector/formatting/resources/css-tests/keyframes-expected.css (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/css-tests/keyframes-expected.css	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/css-tests/keyframes-expected.css	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1,10 @@
+@-webkit-keyframes spin {
+    0% {
+        -webkit-transform: rotate(-180deg) translate(0px, 0px);
+    }
+
+    100% {
+        -webkit-transform: rotate(180deg) translate(10px, 75px);
+    }
+}
+

Added: trunk/LayoutTests/inspector/formatting/resources/css-tests/keyframes.css (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/css-tests/keyframes.css	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/css-tests/keyframes.css	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1 @@
+@-webkit-keyframes spin{0%{-webkit-transform:rotate(-180deg)translate(0px,0px);}100%{-webkit-transform:rotate(180deg)translate(10px,75px);}}

Added: trunk/LayoutTests/inspector/formatting/resources/css-tests/media-query-expected.css (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/css-tests/media-query-expected.css	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/css-tests/media-query-expected.css	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1,34 @@
+/* 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
+    }
+}
+

Added: trunk/LayoutTests/inspector/formatting/resources/css-tests/media-query.css (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/css-tests/media-query.css	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/css-tests/media-query.css	2019-06-06 23:35:12 UTC (rev 246178)
@@ -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}}

Added: trunk/LayoutTests/inspector/formatting/resources/css-tests/selectors-expected.css (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/css-tests/selectors-expected.css	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/css-tests/selectors-expected.css	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1,9 @@
+/* SHORT SELECTOR, EMPTY CONTENT */
+a {
+}
+
+/* COMPLEX SELECTOR */
+div div > div#id.foo.bar:hover .something > .child ~ .sibling + .sibling::after {
+    color: red;
+}
+

Added: trunk/LayoutTests/inspector/formatting/resources/css-tests/selectors.css (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/css-tests/selectors.css	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/css-tests/selectors.css	2019-06-06 23:35:12 UTC (rev 246178)
@@ -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;}

Added: trunk/LayoutTests/inspector/formatting/resources/css-tests/wrapping-expected.css (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/css-tests/wrapping-expected.css	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/css-tests/wrapping-expected.css	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1,9 @@
+/* LONG LISTS SHOULDN'T WRAP */
+a.browsewebappss, a.businessstores, a.buyiphones, a.buynows, a.buynows-arrow, a.comingsoons, p::before, a.descargarahoras, a.downloadituness, a.downloadnows, a.finds, a.freetrials, a.getstarteds, a.gos, a.howtoapplys, a.howtobuys, a.joinnows, a.learnmores, a.nikebuynows, a.notifymes, a.ordernows, a.preordernows, a.preorders, a.reserves, a.startyoursearchs, a.submits, a.tryamacs, a.upgradenows {
+    color: red
+}
+
+a.browsewebappss:hover, a.businessstores:hover, a.buyiphones:hover, a.buynows:hover, a.buynows-arrow:hover, a.comingsoons:hover, p::before, a.descargarahoras:hover, a.downloadituness:hover, a.downloadnows:hover, a.finds:hover, a.freetrials:hover, a.getstarteds:hover, a.gos:hover, a.howtoapplys:hover, a.howtobuys:hover, a.joinnows:hover, a.learnmores:hover, a.nikebuynows:hover, a.notifymes:hover, a.ordernows:hover, a.preordernows:hover, a.preorders:hover, a.reserves:hover, a.startyoursearchs:hover, a.submits:hover, a.tryamacs:hover, a.upgradenows:hover {
+    color: red
+}
+

Added: trunk/LayoutTests/inspector/formatting/resources/css-tests/wrapping.css (0 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/css-tests/wrapping.css	                        (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/css-tests/wrapping.css	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1,3 @@
+/* LONG LISTS SHOULDN'T WRAP */
+a.browsewebappss,a.businessstores,a.buyiphones,a.buynows,a.buynows-arrow,a.comingsoons,p::before,a.descargarahoras,a.downloadituness,a.downloadnows,a.finds,a.freetrials,a.getstarteds,a.gos,a.howtoapplys,a.howtobuys,a.joinnows,a.learnmores,a.nikebuynows,a.notifymes,a.ordernows,a.preordernows,a.preorders,a.reserves,a.startyoursearchs,a.submits,a.tryamacs,a.upgradenows {color:red}
+a.browsewebappss:hover,a.businessstores:hover,a.buyiphones:hover,a.buynows:hover,a.buynows-arrow:hover,a.comingsoons:hover,p::before,a.descargarahoras:hover,a.downloadituness:hover,a.downloadnows:hover,a.finds:hover,a.freetrials:hover,a.getstarteds:hover,a.gos:hover,a.howtoapplys:hover,a.howtobuys:hover,a.joinnows:hover,a.learnmores:hover,a.nikebuynows:hover,a.notifymes:hover,a.ordernows:hover,a.preordernows:hover,a.preorders:hover,a.reserves:hover,a.startyoursearchs:hover,a.submits:hover,a.tryamacs:hover,a.upgradenows:hover {color:red}

Modified: trunk/LayoutTests/inspector/formatting/resources/utilities.js (246177 => 246178)


--- trunk/LayoutTests/inspector/formatting/resources/utilities.js	2019-06-06 23:31:40 UTC (rev 246177)
+++ trunk/LayoutTests/inspector/formatting/resources/utilities.js	2019-06-06 23:35:12 UTC (rev 246178)
@@ -13,10 +13,10 @@
         return loadFormattingTestAndExpectedResults(testURL).then(function(results) {
             let {testText, expectedText} = results;
             return new Promise(function(resolve, reject) {
+                let workerProxy = WI.FormatterWorkerProxy.singleton();
                 const indentString = "    ";
-                let workerProxy = WI.FormatterWorkerProxy.singleton();
-                let isModule = /^module/.test(testName);
-                workerProxy.formatJavaScript(testText, isModule, indentString, ({formattedText, sourceMapData}) => {
+
+                function callback({formattedText, sourceMapData}) {
                     let pass = formattedText === expectedText;
                     InspectorTest.log(pass ? "PASS" : "FAIL");
 
@@ -36,7 +36,19 @@
                     }
 
                     resolve(pass);
-                });
+                }
+
+                switch (mode) {
+                case "text/_javascript_": {
+                    let isModule = /^module/.test(testName);
+                    workerProxy.formatJavaScript(testText, isModule, indentString, callback);
+                    break;
+                }
+
+                case "text/css":
+                    workerProxy.formatCSS(testText, indentString, callback);
+                    break;
+                }
             });
         });
     }

Modified: trunk/Source/WebInspectorUI/.eslintrc (246177 => 246178)


--- trunk/Source/WebInspectorUI/.eslintrc	2019-06-06 23:31:40 UTC (rev 246177)
+++ trunk/Source/WebInspectorUI/.eslintrc	2019-06-06 23:35:12 UTC (rev 246178)
@@ -90,6 +90,7 @@
         "esprima": true,
 
         // Formatters
+        "CSSFormatter": true,
         "ESTreeWalker": true,
         "EsprimaFormatter": true,
         "FormatterWorker": true,

Modified: trunk/Source/WebInspectorUI/ChangeLog (246177 => 246178)


--- trunk/Source/WebInspectorUI/ChangeLog	2019-06-06 23:31:40 UTC (rev 246177)
+++ trunk/Source/WebInspectorUI/ChangeLog	2019-06-06 23:35:12 UTC (rev 246178)
@@ -1,5 +1,33 @@
 2019-06-06  Devin Rousso  <[email protected]>
 
+        Web Inspector: Formatter: pretty-print CSS using a Worker
+        https://bugs.webkit.org/show_bug.cgi?id=197829
+        <rdar://problem/36891532>
+
+        Reviewed by Timothy Hatcher.
+
+        * UserInterface/Proxies/FormatterWorkerProxy.js:
+        (WI.FormatterWorkerProxy.prototype.formatCSS): Added.
+        * UserInterface/Workers/Formatter/FormatterWorker.js:
+        (FormatterWorker.prototype.formatCSS): Added.
+        * UserInterface/Workers/Formatter/CSSFormatter.js: Added.
+        (CSSFormatter):
+        (CSSFormatter.prototype.get success):
+        (CSSFormatter.prototype.get formattedText):
+        (CSSFormatter.prototype.get sourceMapData):
+        (CSSFormatter.prototype._format):
+
+        * UserInterface/Workers/Formatter/FormatterContentBuilder.js:
+        (FormatterContentBuilder.prototype.get currentLine): Added.
+
+        * UserInterface/Views/TextEditor.js:
+        (WI.TextEditor.prototype._canUseFormatterWorker):
+        (WI.TextEditor.prototype._startWorkerPrettyPrint):
+
+        * .eslintrc:
+
+2019-06-06  Devin Rousso  <[email protected]>
+
         Web Inspector: Elements: print/rulers/compositing/paint navigation items shouldn't be visible if the inspected target doesn't have a PageAgent
         https://bugs.webkit.org/show_bug.cgi?id=198410
 

Modified: trunk/Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js (246177 => 246178)


--- trunk/Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js	2019-06-06 23:31:40 UTC (rev 246177)
+++ trunk/Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js	2019-06-06 23:35:12 UTC (rev 246178)
@@ -50,6 +50,11 @@
         this.performAction("formatJavaScript", ...arguments);
     }
 
+    formatCSS(sourceText, indentString, includeSourceMapData)
+    {
+        this.performAction("formatCSS", ...arguments);
+    }
+
     // Public
 
     performAction(actionName)

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js (246177 => 246178)


--- trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js	2019-06-06 23:31:40 UTC (rev 246177)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js	2019-06-06 23:35:12 UTC (rev 246178)
@@ -896,7 +896,8 @@
 
     _canUseFormatterWorker()
     {
-        return this._codeMirror.getMode().name === "_javascript_";
+        let mode = this._codeMirror.getMode().name;
+        return mode === "_javascript_" || mode === "css";
     }
 
     _attemptToDetermineMIMEType()
@@ -919,15 +920,12 @@
 
     _startWorkerPrettyPrint(beforePrettyPrintState, callback)
     {
+        let workerProxy = WI.FormatterWorkerProxy.singleton();
         let sourceText = this._codeMirror.getValue();
         let indentString = WI.indentString();
         const includeSourceMapData = true;
 
-        let sourceType = this._delegate ? this._delegate.textEditorScriptSourceType(this) : WI.Script.SourceType.Program;
-        const isModule = sourceType === WI.Script.SourceType.Module;
-
-        let workerProxy = WI.FormatterWorkerProxy.singleton();
-        workerProxy.formatJavaScript(sourceText, isModule, indentString, includeSourceMapData, ({formattedText, sourceMapData}) => {
+        let formatCallback = ({formattedText, sourceMapData}) => {
             // Handle if formatting failed, which is possible for invalid programs.
             if (formattedText === null) {
                 callback();
@@ -934,7 +932,15 @@
                 return;
             }
             this._finishPrettyPrint(beforePrettyPrintState, formattedText, sourceMapData, callback);
-        });
+        };
+
+        let mode = this._codeMirror.getMode().name;
+        if (mode === "_javascript_") {
+            let sourceType = this._delegate ? this._delegate.textEditorScriptSourceType(this) : WI.Script.SourceType.Program;
+            const isModule = sourceType === WI.Script.SourceType.Module;
+            workerProxy.formatJavaScript(sourceText, isModule, indentString, includeSourceMapData, formatCallback);
+        } else if (mode === "css")
+            workerProxy.formatCSS(sourceText, indentString, includeSourceMapData, formatCallback);
     }
 
     _startCodeMirrorPrettyPrint(beforePrettyPrintState, callback)

Added: trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/CSSFormatter.js (0 => 246178)


--- trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/CSSFormatter.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/CSSFormatter.js	2019-06-06 23:35:12 UTC (rev 246178)
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+CSSFormatter = class CSSFormatter
+{
+    constructor(sourceText, indentString = "    ")
+    {
+        this._success = false;
+
+        this._sourceText = sourceText;
+
+        this._builder = new FormatterContentBuilder(indentString);
+        this._builder.setOriginalLineEndings(this._sourceText.lineEndings());
+
+        this._format();
+
+        this._success = true;
+    }
+
+    // Public
+
+    get success() { return this._success; }
+
+    get formattedText()
+    {
+        if (!this._success)
+            return null;
+        return this._builder.formattedContent;
+    }
+
+    get sourceMapData()
+    {
+        if (!this._success)
+            return null;
+        return this._builder.sourceMapData;
+    }
+
+    // Private
+
+    _format()
+    {
+        const quoteTypes = new Set([`"`, `'`]);
+
+        const dedentBefore = new Set([`}`]);
+
+        const newlineBefore = new Set([`}`]);
+        const newlineAfter = new Set([`{`, `}`, `;`]);
+
+        const indentAfter = new Set([`{`]);
+
+        const addSpaceBefore = new Set([`+`, `*`, `~`, `>`, `(`, `{`, `!`]);
+        const addSpaceAfter = new Set([`,`, `+`, `*`, `~`, `>`, `)`, `:`]);
+
+        const removeSpaceBefore = new Set([`,`, `(`, `)`, `}`, `:`, `;`]);
+        const removeSpaceAfter = new Set([`(`, `{`, `}`, `!`, `;`]);
+
+        for (let i = 0; i < this._sourceText.length; ++i) {
+            let inSelector = () => {
+                let nextOpenBrace = this._sourceText.indexOf(`{`, i);
+                if (nextOpenBrace !== -1) {
+                    let nextQuote = Infinity;
+                    for (let quoteType of quoteTypes) {
+                        let quoteIndex = this._sourceText.indexOf(quoteType, i);
+                        if (quoteIndex !== -1 && quoteIndex < nextQuote)
+                            nextQuote = quoteIndex;
+                    }
+                    if (nextOpenBrace < nextQuote) {
+                        let nextSemicolon = this._sourceText.indexOf(`;`, i);
+                        if (nextSemicolon === -1)
+                            nextSemicolon = Infinity;
+
+                        let nextNewline = this._sourceText.indexOf(`\n`, i);
+                        if (nextNewline === -1)
+                            nextNewline = Infinity;
+
+                        if (nextOpenBrace < Math.min(nextSemicolon, nextNewline))
+                            return true;
+                    }
+                }
+
+                if (!/^\s+[-_a-zA-Z][-_a-zA-Z0-9]*/.test(this._builder.currentLine))
+                    return true;
+
+                return false;
+            };
+
+            let inMediaQuery = () => {
+                return /^\s*@media/.test(this._builder.currentLine);
+            };
+
+            let formatBefore = () => {
+                if (this._builder.lastNewlineAppendWasMultiple && c === `}`)
+                    this._builder.removeLastNewline();
+
+                if (dedentBefore.has(c))
+                    this._builder.dedent();
+
+                if (!this._builder.lastNewlineAppendWasMultiple && newlineBefore.has(c))
+                    this._builder.appendNewline();
+
+                if (!this._builder.lastTokenWasWhitespace && addSpaceBefore.has(c)) {
+                    if (c !== `(` || inMediaQuery())
+                        this._builder.appendSpace();
+                }
+
+                if (this._builder.lastTokenWasWhitespace && removeSpaceBefore.has(c)) {
+                    if ((c !== `:` || !inSelector()) && (c !== `(` || !inMediaQuery() || this._sourceText[i - 1] === `(`))
+                        this._builder.removeLastWhitespace();
+                }
+            };
+
+            let formatAfter = () => {
+                if (this._builder.lastTokenWasWhitespace && removeSpaceAfter.has(c)) {
+                    if (c !== `(` || inMediaQuery())
+                        this._builder.removeLastWhitespace();
+                }
+
+                if (!this._builder.lastTokenWasWhitespace && addSpaceAfter.has(c)) {
+                    if (c !== `:` || !inSelector())
+                        this._builder.appendSpace();
+                }
+
+                if (indentAfter.has(c))
+                    this._builder.indent();
+
+                if (newlineAfter.has(c)) {
+                    if (c === `}`)
+                        this._builder.appendMultipleNewlines(2);
+                    else
+                        this._builder.appendNewline();
+                }
+            };
+
+            let c = this._sourceText[i];
+
+            let specialSequenceEnd = null;
+            if (quoteTypes.has(c))
+                specialSequenceEnd = c;
+            else if (c === `/` && this._sourceText[i + 1] === `*`)
+                specialSequenceEnd = `*/`;
+            else if (c === `u` && this._sourceText[i + 1] === `r` && this._sourceText[i + 2] === `l` && this._sourceText[i + 3] === `(`)
+                specialSequenceEnd = `)`;
+
+            if (specialSequenceEnd) {
+                let endIndex = i;
+                do {
+                    endIndex = this._sourceText.indexOf(specialSequenceEnd, endIndex + specialSequenceEnd.length);
+                } while (endIndex !== -1 && this._sourceText[endIndex - 1] === `\\`);
+
+                if (endIndex === -1)
+                    endIndex = this._sourceText.length;
+
+                this._builder.appendToken(this._sourceText.substring(i, endIndex + specialSequenceEnd.length), i);
+                i = endIndex + specialSequenceEnd.length - 1; // Account for the iteration of the for loop.
+
+                c = this._sourceText[i];
+                formatAfter();
+                continue;
+            }
+
+            if (/\s/.test(c)) {
+                if (c === `\n` && !this._builder.lastTokenWasNewline) {
+                    this._builder.removeLastWhitespace();
+                    this._builder.appendNewline();
+                } else if (!this._builder.lastTokenWasWhitespace && !removeSpaceAfter.has(this._sourceText[i - 1]))
+                    this._builder.appendSpace();
+                continue;
+            }
+
+            formatBefore();
+            this._builder.appendToken(c, i);
+            formatAfter();
+        }
+
+        this._builder.finish();
+    }
+};

Modified: trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterContentBuilder.js (246177 => 246178)


--- trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterContentBuilder.js	2019-06-06 23:31:40 UTC (rev 246177)
+++ trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterContentBuilder.js	2019-06-06 23:35:12 UTC (rev 246178)
@@ -74,6 +74,11 @@
         };
     }
 
+    get currentLine()
+    {
+        return this._formattedContent.slice(this._formattedContent.lastIndexOf("\n") + 1).join("");
+    }
+
     setOriginalContent(originalContent)
     {
         console.assert(!this._originalContent);

Modified: trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterWorker.js (246177 => 246178)


--- trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterWorker.js	2019-06-06 23:31:40 UTC (rev 246177)
+++ trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterWorker.js	2019-06-06 23:35:12 UTC (rev 246178)
@@ -29,6 +29,7 @@
     "FormatterContentBuilder.js",
     "ESTreeWalker.js",
     "EsprimaFormatter.js",
+    "CSSFormatter.js",
 ]);
 
 FormatterWorker = class FormatterWorker
@@ -88,6 +89,18 @@
         return {formattedText: null};
     }
 
+    formatCSS(sourceText, indentString, includeSourceMapData)
+    {
+        let result = {formattedText: null};
+        let formatter = new CSSFormatter(sourceText, indentString);
+        if (formatter.success) {
+            result.formattedText = formatter.formattedText;
+            if (includeSourceMapData)
+                result.sourceMapData = formatter.sourceMapData;
+        }
+        return result;
+    }
+
     // Private
 
     _handleMessage(event)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to