WebKit Bugzilla
Attachment 369944 Details for
Bug 197829
: Web Inspector: Formatter: pretty-print CSS using a Worker
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-197829-20190515035657.patch (text/plain), 32.45 KB, created by
Devin Rousso
on 2019-05-15 03:56:58 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Devin Rousso
Created:
2019-05-15 03:56:58 PDT
Size:
32.45 KB
patch
obsolete
>diff --git a/Source/WebInspectorUI/ChangeLog b/Source/WebInspectorUI/ChangeLog >index eafa215585124fc48807022fe0541ed3c2d3ad7e..66f232c3365e5481749222e96aa8b76df309c453 100644 >--- a/Source/WebInspectorUI/ChangeLog >+++ b/Source/WebInspectorUI/ChangeLog >@@ -1,3 +1,31 @@ >+2019-05-15 Devin Rousso <drousso@apple.com> >+ >+ Web Inspector: Formatter: pretty-print CSS using a Worker >+ https://bugs.webkit.org/show_bug.cgi?id=197829 >+ <rdar://problem/36891532> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * 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-05-09 Devin Rousso <drousso@apple.com> > > Web Inspector: Uncaught Exception: null is not an object (evaluating 'resource.parentFrame.securityOrigin') >diff --git a/Source/WebInspectorUI/.eslintrc b/Source/WebInspectorUI/.eslintrc >index e503f7c75d968a74b7542550895aadff62552669..fc6d0eaa251eec221a95e1035ec49fd00e54b205 100644 >--- a/Source/WebInspectorUI/.eslintrc >+++ b/Source/WebInspectorUI/.eslintrc >@@ -90,6 +90,7 @@ > "esprima": true, > > // Formatters >+ "CSSFormatter": true, > "ESTreeWalker": true, > "EsprimaFormatter": true, > "FormatterWorker": true, >diff --git a/Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js b/Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js >index fca1005d0a5f5012d58eaa4d8f2e0b9dc9fded9b..9258894a7a08f6af0854b8e06bd56ebaac904641 100644 >--- a/Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js >+++ b/Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js >@@ -50,6 +50,11 @@ WI.FormatterWorkerProxy = class FormatterWorkerProxy > this.performAction("formatJavaScript", ...arguments); > } > >+ formatCSS(sourceText, indentString, includeSourceMapData) >+ { >+ this.performAction("formatCSS", ...arguments); >+ } >+ > // Public > > performAction(actionName) >diff --git a/Source/WebInspectorUI/UserInterface/Views/TextEditor.js b/Source/WebInspectorUI/UserInterface/Views/TextEditor.js >index 814f24b7e08c068f0dc36f541a12ab3cd204eb71..f16ee734fadfe0cfc40779118d88b67d0ce7735c 100644 >--- a/Source/WebInspectorUI/UserInterface/Views/TextEditor.js >+++ b/Source/WebInspectorUI/UserInterface/Views/TextEditor.js >@@ -896,7 +896,8 @@ WI.TextEditor = class TextEditor extends WI.View > > _canUseFormatterWorker() > { >- return this._codeMirror.getMode().name === "javascript"; >+ let mode = this._codeMirror.getMode().name; >+ return mode === "javascript" || mode === "css"; > } > > _attemptToDetermineMIMEType() >@@ -919,22 +920,27 @@ WI.TextEditor = class TextEditor extends WI.View > > _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(); > 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) >diff --git a/Source/WebInspectorUI/UserInterface/Workers/Formatter/CSSFormatter.js b/Source/WebInspectorUI/UserInterface/Workers/Formatter/CSSFormatter.js >new file mode 100644 >index 0000000000000000000000000000000000000000..3847f8a5b08f74ba552464472debdb63fe48e224 >--- /dev/null >+++ b/Source/WebInspectorUI/UserInterface/Workers/Formatter/CSSFormatter.js >@@ -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(); >+ } >+}; >diff --git a/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterContentBuilder.js b/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterContentBuilder.js >index a60a27e32c0bf12619ee3dba18090014478a02b4..a2de66a1327e8a5d669fc8272df82bae5d2a5778 100644 >--- a/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterContentBuilder.js >+++ b/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterContentBuilder.js >@@ -74,6 +74,11 @@ FormatterContentBuilder = class FormatterContentBuilder > }; > } > >+ get currentLine() >+ { >+ return this._formattedContent.slice(this._formattedContent.lastIndexOf("\n") + 1).join(""); >+ } >+ > setOriginalContent(originalContent) > { > console.assert(!this._originalContent); >diff --git a/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterWorker.js b/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterWorker.js >index 0f5c8450d283e7b55bf54b92a97ae67c5d2cc5b2..bccd10fc39327c3b27163a072ad17607bd7573d3 100644 >--- a/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterWorker.js >+++ b/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterWorker.js >@@ -29,6 +29,7 @@ importScripts(...[ > "FormatterContentBuilder.js", > "ESTreeWalker.js", > "EsprimaFormatter.js", >+ "CSSFormatter.js", > ]); > > FormatterWorker = class FormatterWorker >@@ -88,6 +89,18 @@ FormatterWorker = class FormatterWorker > 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) >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index f28c4e048d1eaa742e1676739e77059f5c549b0e..8b95ea1bc25baa85bae255aad29a86c8be2d414b 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,28 @@ >+2019-05-15 Devin Rousso <drousso@apple.com> >+ >+ Web Inspector: Formatter: pretty-print CSS using a Worker >+ https://bugs.webkit.org/show_bug.cgi?id=197829 >+ <rdar://problem/36891532> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * 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-05-14 Wenson Hsieh <wenson_hsieh@apple.com> > > Missing cursor/caret showing in search field on google.com >diff --git a/LayoutTests/inspector/formatting/formatting-css-expected.txt b/LayoutTests/inspector/formatting/formatting-css-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..a7c70df8407c2fc482c587331d5b01fbcf26ade5 >--- /dev/null >+++ b/LayoutTests/inspector/formatting/formatting-css-expected.txt >@@ -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 >+ >diff --git a/LayoutTests/inspector/formatting/formatting-css.html b/LayoutTests/inspector/formatting/formatting-css.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0324c21c7de944d03be6780764b0d63a1b8f6ab2 >--- /dev/null >+++ b/LayoutTests/inspector/formatting/formatting-css.html >@@ -0,0 +1,27 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script src="../../http/tests/inspector/resources/inspector-test.js"></script> >+<script src="resources/utilities.js"></script> >+<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> >diff --git a/LayoutTests/inspector/formatting/resources/css-tests/basic-expected.css b/LayoutTests/inspector/formatting/resources/css-tests/basic-expected.css >new file mode 100644 >index 0000000000000000000000000000000000000000..27013770c8fb360ff8e7dfb27470a4efdc27e3c1 >--- /dev/null >+++ b/LayoutTests/inspector/formatting/resources/css-tests/basic-expected.css >@@ -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 >+} >+ >diff --git a/LayoutTests/inspector/formatting/resources/css-tests/basic.css b/LayoutTests/inspector/formatting/resources/css-tests/basic.css >new file mode 100644 >index 0000000000000000000000000000000000000000..0bf7c48d77a67903f1bda1972e0cc844500e2237 >--- /dev/null >+++ b/LayoutTests/inspector/formatting/resources/css-tests/basic.css >@@ -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} >diff --git a/LayoutTests/inspector/formatting/resources/css-tests/gradient-expected.css b/LayoutTests/inspector/formatting/resources/css-tests/gradient-expected.css >new file mode 100644 >index 0000000000000000000000000000000000000000..73358173407cac0c0b3b7478b2e0fa1eb9d982a6 >--- /dev/null >+++ b/LayoutTests/inspector/formatting/resources/css-tests/gradient-expected.css >@@ -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%); >+} >+ >diff --git a/LayoutTests/inspector/formatting/resources/css-tests/gradient.css b/LayoutTests/inspector/formatting/resources/css-tests/gradient.css >new file mode 100644 >index 0000000000000000000000000000000000000000..f3562ad4a87870026fcb920f56a9d622ddfef062 >--- /dev/null >+++ b/LayoutTests/inspector/formatting/resources/css-tests/gradient.css >@@ -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%); >+} >diff --git a/LayoutTests/inspector/formatting/resources/css-tests/keyframes-expected.css b/LayoutTests/inspector/formatting/resources/css-tests/keyframes-expected.css >new file mode 100644 >index 0000000000000000000000000000000000000000..e7106720447fdd05d3ea98264fca41c921b74e2e >--- /dev/null >+++ b/LayoutTests/inspector/formatting/resources/css-tests/keyframes-expected.css >@@ -0,0 +1,10 @@ >+@-webkit-keyframes spin { >+ 0% { >+ -webkit-transform: rotate(-180deg) translate(0px, 0px); >+ } >+ >+ 100% { >+ -webkit-transform: rotate(180deg) translate(10px, 75px); >+ } >+} >+ >diff --git a/LayoutTests/inspector/formatting/resources/css-tests/keyframes.css b/LayoutTests/inspector/formatting/resources/css-tests/keyframes.css >new file mode 100644 >index 0000000000000000000000000000000000000000..bd88b56cc49697b78200bb99dd0f4297236f4483 >--- /dev/null >+++ b/LayoutTests/inspector/formatting/resources/css-tests/keyframes.css >@@ -0,0 +1 @@ >+@-webkit-keyframes spin{0%{-webkit-transform:rotate(-180deg)translate(0px,0px);}100%{-webkit-transform:rotate(180deg)translate(10px,75px);}} >diff --git a/LayoutTests/inspector/formatting/resources/css-tests/media-query-expected.css b/LayoutTests/inspector/formatting/resources/css-tests/media-query-expected.css >new file mode 100644 >index 0000000000000000000000000000000000000000..02ebe939e1ce860301e50fed93af0605a12a6e7a >--- /dev/null >+++ b/LayoutTests/inspector/formatting/resources/css-tests/media-query-expected.css >@@ -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 >+ } >+} >+ >diff --git a/LayoutTests/inspector/formatting/resources/css-tests/media-query.css b/LayoutTests/inspector/formatting/resources/css-tests/media-query.css >new file mode 100644 >index 0000000000000000000000000000000000000000..b86bcffc09a2e879abc977ca2a438d5430dd085f >--- /dev/null >+++ b/LayoutTests/inspector/formatting/resources/css-tests/media-query.css >@@ -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/LayoutTests/inspector/formatting/resources/css-tests/selectors-expected.css b/LayoutTests/inspector/formatting/resources/css-tests/selectors-expected.css >new file mode 100644 >index 0000000000000000000000000000000000000000..04201811fc680317f7f6a9d10bad528c0612159b >--- /dev/null >+++ b/LayoutTests/inspector/formatting/resources/css-tests/selectors-expected.css >@@ -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; >+} >+ >diff --git a/LayoutTests/inspector/formatting/resources/css-tests/selectors.css b/LayoutTests/inspector/formatting/resources/css-tests/selectors.css >new file mode 100644 >index 0000000000000000000000000000000000000000..5a3ef7c4b47aad4a629686c5297fbe28ba5a2981 >--- /dev/null >+++ b/LayoutTests/inspector/formatting/resources/css-tests/selectors.css >@@ -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;} >diff --git a/LayoutTests/inspector/formatting/resources/css-tests/wrapping-expected.css b/LayoutTests/inspector/formatting/resources/css-tests/wrapping-expected.css >new file mode 100644 >index 0000000000000000000000000000000000000000..795d5dc9eb3ab8cf54ba0e502bd2dcb04db2c8a3 >--- /dev/null >+++ b/LayoutTests/inspector/formatting/resources/css-tests/wrapping-expected.css >@@ -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 >+} >+ >diff --git a/LayoutTests/inspector/formatting/resources/css-tests/wrapping.css b/LayoutTests/inspector/formatting/resources/css-tests/wrapping.css >new file mode 100644 >index 0000000000000000000000000000000000000000..be6bf9d2aa84b2f1549fb990d69717857308ee1d >--- /dev/null >+++ b/LayoutTests/inspector/formatting/resources/css-tests/wrapping.css >@@ -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} >diff --git a/LayoutTests/inspector/formatting/resources/utilities.js b/LayoutTests/inspector/formatting/resources/utilities.js >index 9b4e326ec043e5cfbaec2f304859bfd9f2ba7de5..519ec4d9cef4806b2d4f2139e64bf24b141f0e80 100644 >--- a/LayoutTests/inspector/formatting/resources/utilities.js >+++ b/LayoutTests/inspector/formatting/resources/utilities.js >@@ -13,10 +13,10 @@ TestPage.registerInitializer(function() { > return loadFormattingTestAndExpectedResults(testURL).then(function(results) { > let {testText, expectedText} = results; > return new Promise(function(resolve, reject) { >- const indentString = " "; > let workerProxy = WI.FormatterWorkerProxy.singleton(); >- let isModule = /^module/.test(testName); >- workerProxy.formatJavaScript(testText, isModule, indentString, ({formattedText, sourceMapData}) => { >+ const indentString = " "; >+ >+ function callback({formattedText, sourceMapData}) { > let pass = formattedText === expectedText; > InspectorTest.log(pass ? "PASS" : "FAIL"); > >@@ -36,7 +36,19 @@ TestPage.registerInitializer(function() { > } > > 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; >+ } > }); > }); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 197829
:
369695
|
369736
| 369944