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)