Merge pull request #2791 from lydell/playground

Improve the playground
master
Simon Lydell 2017-09-14 12:24:02 +02:00 committed by GitHub
commit 457903ff74
8 changed files with 626 additions and 244 deletions

View File

@ -1,15 +1,28 @@
<!-- BUGS: Please use this template. -->
<!-- BUGGY OR UGLY? Please use this template.
**Prettier Version:** 1.6.1 / master
Tip! Don't write this stuff manually.
**Code**
1. Go to https://prettier.io/playground
2. Paste your code and set options
3. Press the "Report issue" button in the lower right
([playground](https://prettier.io/playground/#.....))
-->
```js
**Prettier 1.6.1**
[Playground link](https://prettier.io/playground/#.....)
```sh
# Options (if any):
--single-quote
```
**Input:**
```jsx
// code snippet
```
**Output:**
```jsx
// code snippet
```
**Expected behavior:**
**Actual behavior:**

View File

@ -4,6 +4,7 @@
const path = require("path");
const pkg = require("../../package.json");
const formatMarkdown = require("../../website/static/markdown");
const shell = require("shelljs");
const rootDir = path.join(__dirname, "..", "..");
@ -99,15 +100,22 @@ shell.sed(
);
shell.echo("Update ISSUE_TEMPLATE.md");
shell.sed(
"-i",
/(Prettier Version.+?)\d+\.\d+\.\d+/,
`$1${pkg.version}`,
".github/ISSUE_TEMPLATE.md"
const issueTemplate = shell.cat(".github/ISSUE_TEMPLATE.md").stdout;
const newIssueTemplate = issueTemplate.replace(
/-->[^]*$/,
"-->\n\n" +
formatMarkdown(
"// code snippet",
"// code snippet",
"",
pkg.version,
"https://prettier.io/playground/#.....",
{ parser: "babylon" },
[["# Options (if any):", true], ["--single-quote", true]],
true
)
);
shell.echo("Create prettier-version.js");
pipe(`prettierVersion = "${pkg.version}";\n`).to(`${docs}/prettier-version.js`);
pipe(newIssueTemplate).to(".github/ISSUE_TEMPLATE.md");
shell.echo("Copy sw-toolbox.js to docs");
shell.cp("node_modules/sw-toolbox/sw-toolbox.js", `${docs}/sw-toolbox.js`);

View File

@ -1,5 +1,5 @@
<!doctype html>
<html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
@ -11,8 +11,8 @@
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="application-name" content="Prettier">
<meta name="apple-mobile-web-app-title" content="Prettier">
<meta name="theme-color" content="#1A2B34">
<meta name="msapplication-navbutton-color" content="#1A2B34">
<meta name="theme-color" content="#1a2b34">
<meta name="msapplication-navbutton-color" content="#1a2b34">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="msapplication-starturl" content="/">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
@ -21,13 +21,15 @@
<link rel="apple-touch-icon" href="/icon.png">
<link rel="stylesheet" crossorigin href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/codemirror.css">
<link rel="stylesheet" crossorigin href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/theme/neat.css">
<script src="/lib/prettier-version.js"></script>
<script src="/markdown.js"></script>
<script src="/playground.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/codemirror.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/mode/javascript/javascript.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/mode/xml/xml.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/mode/jsx/jsx.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/mode/css/css.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/addon/display/rulers.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/addon/search/searchcursor.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/addon/edit/matchbrackets.js"></script>
@ -35,93 +37,79 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/addon/comment/comment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/addon/wrap/hardwrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/keymap/sublime.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.7.1/clipboard.min.js"></script>
<style type="text/css">
html,
body {
font-family: "Helvetica Neue", "Open Sans", sans-serif;
font-size: 11.7px;
margin: 0;
padding: 0;
background-color: #FAFAFA;
color: #6A6A6A;
html {
background-color: #fafafa;
color: #6a6a6a;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
font-size: 12px;
line-height: 1.25;
}
body {
display: flex;
flex-direction: column;
height: 100vh;
}
.options-summary {
font-size: 1.4em;
margin-top: 8px;
text-align: center;
margin: 0;
}
header {
height: 30px;
padding: 10px 10px;
display: flex;
flex-flow: row nowrap;
position: relative;
text-align: left;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
background-color: #1A2B34;
height: 30px;
padding: 10px 27px;
background-color: #1a2b34;
color: #e0e0e0;
position: relative;
z-index: 20;
}
@media (max-width: 500px) {
.tagline {
display: none;
@media (max-width: 400px) {
header {
padding: 10px;
}
}
header a {
height: 34px;
display: flex;
text-decoration: none;
}
header a,
header a:visited {
color: #fff;
}
header a:visited,
header a:focus,
header a:active,
header a:hover {
color: #fff;
color: white;
text-decoration: none;
}
.logo-wrapper {
display: flex;
align-items: center;
}
.logo {
height: 100%;
margin-left: 10px;
height: 34px;
margin-right: 10px;
}
header h2 {
display: block;
font-family: "Helvetica Neue", Arial, sans-serif;
font-weight: 400;
line-height: 8px;
position: relative;
z-index: 9999;
header h1 {
margin: 0;
font-size: 18px;
font-weight: normal;
}
.links {
font-size: 1.3em;
margin-right: 30px;
display: flex;
font-size: 16px;
}
textarea.loading {
opacity: 0;
.links > * + * {
margin-left: 15px;
}
.editors-container {
display: flex;
flex-grow: 1;
flex: 1;
}
.editors {
@ -131,17 +119,19 @@
}
.editor {
box-sizing: border-box;
display: flex;
flex: 1;
flex-basis: 100%;
flex: 1 1 100%;
position: relative;
border-top: 1px solid #1A2B34;
border-bottom: 1px solid #ddd;
}
/* display as 2x2 grid */
@media (min-width: 800px) {
.editor {
flex-basis: 50%;
border-left: 1px solid #ddd;
margin-left: -1px;
}
}
@ -152,9 +142,8 @@
}
}
.arrow {
align-self: center;
font-size: 1.2em;
.editor.loading {
opacity: 0;
}
.CodeMirror {
@ -164,9 +153,50 @@
left: 0;
right: 0;
bottom: 0;
font-family: Menlo, monospace;
font-size: 11.05px;
line-height: 17.68px;
line-height: 1.6;
}
.bottom-bar {
position: relative;
}
.bottom-bar-buttons {
position: absolute;
z-index: 10;
top: 0;
left: 0;
padding: 8px;
display: flex;
}
.bottom-bar-buttons-right {
left: auto;
right: 0;
}
.bottom-bar-buttons > * + * {
margin-left: 9px;
}
@media (max-width: 799px) {
.bottom-bar-buttons {
top: auto;
bottom: 100%;
padding: 2px;
}
.bottom-bar-buttons > * + * {
margin-left: 2px;
}
}
.options-details {
padding: 8px 0;
}
.options-summary {
font-size: 1.4em;
text-align: center;
}
.options-container {
@ -176,11 +206,11 @@
}
.options {
padding: 0 10px;
display: flex;
flex-flow: column wrap;
flex-grow: 1;
flex: 1;
display: flex;
justify-content: space-around;
padding: 0 10px;
margin: 5px;
margin-bottom: 0;
min-width: 150px;
@ -207,17 +237,71 @@
max-width: 40px;
}
footer {
text-align: center;
/* Copied from the GitHub button styling. */
.btn {
box-sizing: content-box;
display: inline-block;
height: 18px;
padding: 0 5px;
border: 1px solid #d1d2d3;
border-radius: 0.25em;
background-image: linear-gradient(to bottom, #fafbfc, #e4ebf0);
font-size: 11px;
line-height: 18px;
font-weight: 600;
font-family: inherit;
color: inherit;
text-decoration: none;
cursor: pointer;
outline: none;
position: relative;
}
.btn:focus {
border-color: #c8e1ff;
}
.btn:hover {
background-color:#e6ebf1;
background-image: linear-gradient(to bottom, #f0f3f6, #dce3ec);
border-color:#afb1b2;
}
.btn:active {
background-color: #e9ecef;
background-image: none;
border-color: #afb1b2;
box-shadow: inset 0 0.15em 0.3em rgba(27, 31, 35, 0.15);
}
.tooltip {
position: absolute;
z-index: 1;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
margin-top: 4px;
padding: 0.4em 0.8em;
background-color: black;
color: white;
border-radius: 0.4em;
pointer-events: none;
}
.tooltip::before {
content: "";
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
border: 6px solid transparent;
border-bottom: none;
border-top-color: black;
}
</style>
</head>
<body>
<header>
<a href="/">
<img class="logo" src="/icon.png">
<h2>Prettier</h2>
<a href="/" class="logo-wrapper">
<img class="logo" src="/icon.png" alt="">
<h1>Prettier <span id="version"></span></h1>
</a>
<span class="links">
@ -231,59 +315,73 @@
</span>
</header>
<section class="editors-container">
<div class="editors-container">
<div class="editors">
<div class="editor input">
<textarea class="loading" id="input-editor"></textarea>
<div class="editor loading input">
<textarea id="input-editor"></textarea>
</div>
<div class="editor ast">
<textarea class="loading" id="ast-editor"></textarea>
<div class="editor loading ast">
<textarea id="ast-editor"></textarea>
</div>
<div class="editor doc">
<textarea class="loading" id="doc-editor"></textarea>
<div class="editor loading doc">
<textarea id="doc-editor"></textarea>
</div>
<div class="editor output">
<textarea class="loading" id="output-editor"></textarea>
<div class="editor loading output">
<textarea id="output-editor"></textarea>
</div>
<div class="editor loading output2">
<textarea id="output2-editor"></textarea>
</div>
</div>
</section>
</div>
<section>
<details>
<div class="bottom-bar">
<div class="bottom-bar-buttons">
<button type="button" class="btn" id="button-clear">
Clear
</button>
</div>
<details class="options-details">
<summary class="options-summary">Options</summary>
<div class="options-container">
<div class="options">
<label>--print-width <input type="number" value="80" min="0" id="printWidth"></input> </label>
<label>--tab-width <input type="number" min="0" value="2" id="tabWidth"></input> </label>
<label>--print-width <input type="number" value="80" min="0" id="printWidth"></label>
<label>--tab-width <input type="number" min="0" value="2" id="tabWidth"></label>
</div>
<div class="options">
<label><input type="checkbox" id="useTabs"></input> --use-tabs</label>
<label><input type="checkbox" data-inverted id="semi"></input> --no-semi</label>
<label><input type="checkbox" id="singleQuote"></input> --single-quote</label>
<label><input type="checkbox" data-inverted id="bracketSpacing"></input> --no-bracket-spacing</label>
<label><input type="checkbox" id="jsxBracketSameLine"></input> --jsx-bracket-same-line</label>
<label><input type="checkbox" id="useTabs"> --use-tabs</label>
<label><input type="checkbox" data-inverted id="semi"> --no-semi</label>
<label><input type="checkbox" id="singleQuote"> --single-quote</label>
<label><input type="checkbox" data-inverted id="bracketSpacing"> --no-bracket-spacing</label>
<label><input type="checkbox" id="jsxBracketSameLine"> --jsx-bracket-same-line</label>
</div>
<div class="options last">
<label>--trailing-comma <select id="trailingComma"><option value="none">none</option><option value="es5">es5</option><option value="all">all</option></select></label>
<label>--parser <select id="parser"><option value="babylon">babylon</option><option value="flow">flow</option><option value="typescript">typescript</option><option value="postcss">postcss</option><option value="json">json</option><option value="graphql">graphql</option></select></label>
<span style="flex: 0.3"></span>
<label><input type="checkbox" id="ast"></input> show AST (debug)</label>
<label><input type="checkbox" id="doc"></input> show doc (debug)</label>
<label><input type="checkbox" id="ast"> show AST (debug)</label>
<label><input type="checkbox" id="doc"> show doc (debug)</label>
<label><input type="checkbox" id="output2"> show second format (debug)</label>
</div>
</div>
</details>
</section>
<footer>
<p class="version-link">
<a href="https://github.com/prettier/prettier">
prettier version
<span class="version"></span>
(master)
<div class="bottom-bar-buttons bottom-bar-buttons-right">
<button type="button" class="btn" id="button-copy-link">
Copy link
</button>
<button type="button" class="btn" id="button-copy-markdown">
Copy markdown
</button>
<a href="https://github.com/prettier/prettier/issues/new"
target="_blank" rel="noopener"
class="btn" id="button-report-issue">
Report issue
</a>
</p>
</footer>
</div>
</div>
<script src="/install-service-worker.js"></script>

View File

@ -1 +0,0 @@
prettierVersion = "1.6.1";

View File

@ -0,0 +1,87 @@
/* eslint-env browser */
/* eslint no-var: off, strict: off, prefer-arrow-callback: off */
// NOTE: This file must work both in the playground, and in the build scripts to
// generate the issue template.
(function() {
function formatMarkdown(
input,
output,
output2,
version,
url,
options,
cliOptions,
full
) {
var syntax = getMarkdownSyntax(options);
var optionsString = formatCLIOptions(cliOptions);
var isIdempotent = output2 === "" || output === output2;
return [
"**Prettier " + version + "**",
"[Playground link](" + url + ")",
optionsString === "" ? null : codeBlock(optionsString, "sh"),
"",
"**Input:**",
codeBlock(input, syntax),
"",
"**Output:**",
codeBlock(output, syntax)
]
.concat(
isIdempotent
? []
: ["", "**Second Output:**", codeBlock(output2, syntax)]
)
.concat(full ? ["", "**Expected behavior:**", ""] : [])
.filter(function(part) {
return part != null;
})
.join("\n");
}
function getMarkdownSyntax(options) {
switch (options.parser) {
case "babylon":
case "flow":
return "jsx";
case "typescript":
return "tsx";
case "postcss":
return "scss";
default:
return options.parser;
}
}
function formatCLIOptions(cliOptions) {
return cliOptions
.map(function(option) {
var name = option[0];
var value = option[1];
return value === true ? name : name + " " + value;
})
.join("\n");
}
function codeBlock(content, syntax) {
var backtickSequences = content.match(/`+/g) || [];
var longestBacktickSequenceLength = Math.max.apply(
null,
backtickSequences.map(function(backticks) {
return backticks.length;
})
);
var fenceLength = Math.max(3, longestBacktickSequenceLength + 1);
var fence = Array(fenceLength + 1).join("`");
return [fence + (syntax || ""), content, fence].join("\n");
}
if (typeof module !== "undefined" && module.exports) {
module.exports = formatMarkdown;
} else {
window.formatMarkdown = formatMarkdown;
}
})();

View File

@ -1,6 +1,30 @@
/* eslint-env browser */
/* eslint no-var: off, strict: off, prefer-arrow-callback: off */
/* global CodeMirror prettierVersion */
/* global Clipboard CodeMirror formatMarkdown */
var prettierVersion = "?";
var inputEditor;
var docEditor;
var astEditor;
var outputEditor;
var output2Editor;
var OPTIONS = [
"printWidth",
"tabWidth",
"singleQuote",
"trailingComma",
"bracketSpacing",
"jsxBracketSameLine",
"parser",
"semi",
"useTabs",
"doc",
"ast",
"output2"
];
var IDEMPOTENT_MESSAGE = "✓ Second format is unchanged.";
var state = (function loadState(hash) {
try {
@ -8,147 +32,278 @@ var state = (function loadState(hash) {
} catch (error) {
return {
options: undefined,
content:
'hello ( "world"\n);\n\n' +
'[ "lorem", "ipsum", \'dolor\', sit("amet"), consectetur[ \'adipiscing\' ] + "elit" ].reduce(\n (first, second) => first + second,\n "")\n\n' +
"const Foo = ({ bar, baz, things }) => {\n" +
' return <div style={{\ncolor: "papayawhip"}}>\n' +
" <br/>{things.map(thing => reallyLongPleaseDontPutOnOneLine(thing) ? <p>{ok}</p> : <Quax bar={bar} baz={ baz } {...thing}></Quax>)\n" +
" }</div>}"
content: [
'function HelloWorld({greeting = "hello", greeted = \'"World"\', silent = false, onMouseOver,}) {',
"",
" if(!greeting){return null};",
"",
" // TODO: Don't use random in render",
' let num = Math.floor (Math.random() * 1E+7).toString().replace(/\\.\\d+/ig, "")',
"",
" return <div className='HelloWorld' title={`You are visitor number ${ num }`} onMouseOver={onMouseOver}>",
"",
" <strong>{ greeting.slice( 0, 1 ).toUpperCase() + greeting.slice(1).toLowerCase() }</strong>",
' {greeting.endsWith(",") ? " " : <span style={{color: \'\\grey\'}}>", "</span> }',
" <em>",
"\t{ greeted }",
"\t</em>",
" { (silent)",
' ? "."',
' : "!"}',
"",
" </div>;",
"",
"}"
].join("\n")
};
}
})(decodeURIComponent(location.hash.slice(1)));
var worker = new Worker("/worker.js");
worker.onmessage = function(message) {
if (prettierVersion === "?") {
prettierVersion = message.data.version;
document.getElementById("version").textContent = prettierVersion;
}
if (outputEditor && docEditor && astEditor) {
outputEditor.setValue(message.data.formatted);
docEditor.setValue(message.data.doc || "");
astEditor.setValue(message.data.ast || "");
output2Editor.setValue(
message.data.formatted === ""
? ""
: message.data.formatted2 === message.data.formatted
? IDEMPOTENT_MESSAGE
: message.data.formatted2 || ""
);
document.getElementById("button-report-issue").search =
"body=" + encodeURIComponent(createMarkdown(true));
}
};
// Warm up the worker (load the current parser while CodeMirror loads)
worker.postMessage({ text: "", options: state.options });
window.onload = function() {
var OPTIONS = [
"printWidth",
"tabWidth",
"singleQuote",
"trailingComma",
"bracketSpacing",
"jsxBracketSameLine",
"parser",
"semi",
"useTabs",
"doc",
"ast"
];
state.options && setOptions(state.options);
function setOptions(options) {
OPTIONS.forEach(function(option) {
var elem = document.getElementById(option);
if (elem.tagName === "SELECT") {
elem.value = options[option];
} else if (elem.type === "number") {
elem.value = options[option];
} else {
var isInverted = elem.hasAttribute("data-inverted");
elem.checked = isInverted ? !options[option] : options[option];
}
});
}
function getOptions() {
var options = {};
OPTIONS.forEach(function(option) {
var elem = document.getElementById(option);
if (elem.tagName === "SELECT") {
options[option] = elem.value;
} else if (elem.type === "number") {
options[option] = Number(elem.value);
} else {
var isInverted = elem.hasAttribute("data-inverted");
options[option] = isInverted ? !elem.checked : elem.checked;
}
});
return options;
}
function replaceHash(hash) {
if (
typeof URL === "function" &&
typeof history === "object" &&
typeof history.replaceState === "function"
) {
var url = new URL(location);
url.hash = hash;
history.replaceState(null, null, url);
} else {
location.hash = hash;
}
}
function formatAsync() {
var options = getOptions();
outputEditor.setOption("rulers", [
{ column: options.printWidth, color: "#444444" }
]);
document.querySelector(".ast").style.display = options.ast
? "flex"
: "none";
document.querySelector(".doc").style.display = options.doc
? "flex"
: "none";
var value = encodeURIComponent(
JSON.stringify(
Object.assign({ content: inputEditor.getValue(), options: options })
)
);
replaceHash(value);
worker.postMessage({
text: inputEditor.getValue(),
options: options,
ast: options.ast,
doc: options.doc
});
}
var editorOptions = {
lineNumbers: true,
keyMap: "sublime",
autoCloseBrackets: true,
matchBrackets: true,
showCursorWhenSelecting: true,
theme: "neat",
tabWidth: 2
tabWidth: 2,
mode: "jsx"
};
var inputEditor = CodeMirror.fromTextArea(
inputEditor = CodeMirror.fromTextArea(
document.getElementById("input-editor"),
editorOptions
);
inputEditor.on("change", formatAsync);
var docEditor = CodeMirror.fromTextArea(
document.getElementById("doc-editor"),
{ readOnly: true, lineNumbers: false, theme: "neat" }
);
var astEditor = CodeMirror.fromTextArea(
document.getElementById("ast-editor"),
{ readOnly: true, lineNumbers: false, theme: "neat" }
);
var outputEditor = CodeMirror.fromTextArea(
document.getElementById("output-editor"),
{ readOnly: true, lineNumbers: true, theme: "neat" }
);
Array.from(document.querySelectorAll("textarea")).forEach(function(element) {
element.classList.remove("loading");
docEditor = CodeMirror.fromTextArea(document.getElementById("doc-editor"), {
readOnly: true,
lineNumbers: false,
mode: "jsx"
});
astEditor = CodeMirror.fromTextArea(document.getElementById("ast-editor"), {
readOnly: true,
lineNumbers: false,
mode: "jsx"
});
outputEditor = CodeMirror.fromTextArea(
document.getElementById("output-editor"),
{
readOnly: true,
lineNumbers: true,
mode: "jsx"
}
);
output2Editor = CodeMirror.fromTextArea(
document.getElementById("output2-editor"),
{
readOnly: true,
lineNumbers: true,
mode: "jsx"
}
);
worker.onmessage = function(message) {
outputEditor.setValue(message.data.formatted);
docEditor.setValue(message.data.doc || "");
astEditor.setValue(message.data.ast || "");
};
var editors = document.querySelectorAll(".editor");
for (var i = 0; i < editors.length; i++) {
editors[i].classList.remove("loading");
}
inputEditor.setValue(state.content);
document.querySelector(".options-container").onchange = formatAsync;
document.querySelector(".version").innerText = prettierVersion;
document.getElementById("button-clear").onclick = function() {
inputEditor.setValue("");
};
var clipboard = new Clipboard("#button-copy-link, #button-copy-markdown", {
text: function(trigger) {
switch (trigger.id) {
case "button-copy-link":
return window.location.href;
case "button-copy-markdown":
return createMarkdown();
default:
return "";
}
}
});
clipboard.on("success", function(e) {
showTooltip(e.trigger, "Copied!");
});
clipboard.on("error", function(e) {
showTooltip(e.trigger, "Press ctrl+c to copy");
});
};
function setOptions(options) {
OPTIONS.forEach(function(option) {
var elem = document.getElementById(option);
if (elem.tagName === "SELECT") {
elem.value = options[option];
} else if (elem.type === "number") {
elem.value = options[option];
} else {
var isInverted = elem.hasAttribute("data-inverted");
elem.checked = isInverted ? !options[option] : options[option];
}
});
}
function getOptions() {
var options = {};
OPTIONS.forEach(function(option) {
var elem = document.getElementById(option);
if (elem.tagName === "SELECT") {
options[option] = elem.value;
} else if (elem.type === "number") {
options[option] = Number(elem.value);
} else {
var isInverted = elem.hasAttribute("data-inverted");
options[option] = isInverted ? !elem.checked : elem.checked;
}
});
return options;
}
function getCLIOptions() {
return OPTIONS.sort()
.map(function(option) {
var elem = document.getElementById(option);
var match = elem.parentNode.textContent.match(/--\S+/);
if (!match) {
return null;
}
var name = match[0];
if (elem.tagName === "SELECT") {
if (elem.value === elem.options[0].value) {
return null;
}
return [name, elem.value];
} else if (elem.type === "number") {
if (elem.value === elem.getAttribute("value")) {
return null;
}
return [name, elem.value];
} else if (elem.type === "checkbox") {
if (!elem.checked) {
return null;
}
return [name, true];
}
return null;
})
.filter(Boolean);
}
function replaceHash(hash) {
if (
typeof URL === "function" &&
typeof history === "object" &&
typeof history.replaceState === "function"
) {
var url = new URL(location);
url.hash = hash;
history.replaceState(null, null, url);
} else {
location.hash = hash;
}
}
function getCodemirrorMode(options) {
switch (options.parser) {
case "postcss":
return "css";
default:
return "jsx";
}
}
function formatAsync() {
var options = getOptions();
var mode = getCodemirrorMode(options);
inputEditor.setOption("mode", mode);
outputEditor.setOption("mode", mode);
output2Editor.setOption("mode", mode);
[outputEditor, output2Editor].forEach(function(editor) {
editor.setOption("rulers", [
{ column: options.printWidth, color: "#444444" }
]);
});
document.querySelector(".ast").style.display = options.ast ? "" : "none";
document.querySelector(".doc").style.display = options.doc ? "" : "none";
document.querySelector(".output2").style.display = options.output2
? ""
: "none";
var value = encodeURIComponent(
JSON.stringify(
Object.assign({ content: inputEditor.getValue(), options: options })
)
);
replaceHash(value);
worker.postMessage({
text: inputEditor.getValue(),
options: options,
ast: options.ast,
doc: options.doc,
formatted2: options.output2
});
}
function createMarkdown(full) {
var input = inputEditor.getValue();
var output = outputEditor.getValue();
var output2 = output2Editor.getValue();
var options = getOptions();
var cliOptions = getCLIOptions();
var markdown = formatMarkdown(
input,
output,
output2 === IDEMPOTENT_MESSAGE ? "" : output2,
prettierVersion,
window.location.href,
options,
cliOptions,
full
);
return markdown;
}
function showTooltip(elem, text) {
var tooltip = document.createElement("span");
tooltip.className = "tooltip";
tooltip.textContent = text;
elem.appendChild(tooltip);
window.setTimeout(function() {
elem.removeChild(tooltip);
}, 2000);
}

View File

@ -7,22 +7,24 @@ importScripts("lib/sw-toolbox.js");
toolbox.precache([
// Scripts
"lib/prettier-version.js",
"lib/index.js",
"lib/parser-babylon.js",
"lib/parser-typescript.js",
"lib/parser-postcss.js",
"lib/parser-flow.js",
"lib/parser-graphql.js",
"markdown.js",
"playground.js",
"lib/sw-toolbox.js",
"lib/sw-toolbox-companion.js",
// CodeMirror
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/codemirror.css",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/theme/neat.css",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/codemirror.js",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/mode/javascript/javascript.js",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/mode/xml/xml.js",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/mode/jsx/jsx.js",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/mode/css/css.js",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/addon/display/rulers.js",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/addon/search/searchcursor.js",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/addon/edit/matchbrackets.js",
@ -30,6 +32,7 @@ toolbox.precache([
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/addon/comment/comment.js",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/addon/wrap/hardwrap.js",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.26.0/keymap/sublime.js",
"https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.7.1/clipboard.min.js",
// Images
"/prettier.png"

View File

@ -27,20 +27,29 @@ self.onmessage = function(message) {
delete options.ast;
delete options.doc;
delete options.output2;
var formatted = formatCode(message.data.text, options);
var doc;
var ast;
var formatted2;
if (message.data.ast) {
var actualAst;
var errored = false;
try {
ast = JSON.stringify(
prettier.__debug.parse(message.data.text, options),
null,
2
);
actualAst = prettier.__debug.parse(message.data.text, options);
ast = JSON.stringify(actualAst);
} catch (e) {
ast = e.toString();
errored = true;
ast = String(e);
}
if (!errored) {
try {
ast = formatCode(ast, { parser: "json" });
} catch (e) {
ast = JSON.stringify(actualAst, null, 2);
}
}
}
@ -52,11 +61,21 @@ self.onmessage = function(message) {
{ parser: "babylon" }
);
} catch (e) {
doc = e.toString();
doc = String(e);
}
}
self.postMessage({ formatted: formatted, doc: doc, ast: ast });
if (message.data.formatted2) {
formatted2 = formatCode(formatted, options);
}
self.postMessage({
formatted: formatted,
doc: doc,
ast: ast,
formatted2: formatted2,
version: prettier.version
});
};
function formatCode(text, options) {
@ -70,7 +89,7 @@ function formatCode(text, options) {
lazyLoadParser(e.parser);
return formatCode(text, options);
}
return e.toString();
return String(e);
}
}