Skip to content

Commit

Permalink
Hook up more buttons on the playground
Browse files Browse the repository at this point in the history
  • Loading branch information
orta committed Jan 2, 2020
1 parent e7f3afc commit b33592f
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 58 deletions.
18 changes: 11 additions & 7 deletions packages/playground/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,22 +126,26 @@ export const setupPlayground = (sandbox: Sandbox, monaco: Monaco) => {
}
})

const ui = createUI()
const exporter = createExporter(sandbox, monaco, ui)

const playground = {
exporter,
ui,
}

window.ts = sandbox.ts
window.sandbox = sandbox
window.playground = playground

console.log(`Using TypeScript ${window.ts.version}`)

console.log('Available globals:')
console.log('\twindow.ts', window.ts)
console.log('\twindow.sandbox', window.sandbox)
console.log('\twindow.playground', window.playground)

const ui = createUI()
const exporter = createExporter(sandbox, monaco, ui)

return {
exporter,
ui,
}
return playground
}

export type Playground = ReturnType<typeof setupPlayground>
45 changes: 12 additions & 33 deletions packages/sandbox/src/compilerOptions.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { PlaygroundConfig } from '.'
import LZString from './vendor/lzstring.min'

type CompilerOptions = import('monaco-editor').languages.typescript.CompilerOptions
type Monaco = typeof import('monaco-editor')
type Sandbox = ReturnType<typeof import('.').createTypeScriptSandbox>

/** Our defaults for the playground */
/**
* These are the defaults, but they also act as the list of all compiler options
* which are parsed in the query params.
*/
export function getDefaultSandboxCompilerOptions(config: PlaygroundConfig, monaco: Monaco) {
const settings: CompilerOptions = {
noImplicitAny: true,
Expand Down Expand Up @@ -50,19 +52,21 @@ export function getDefaultSandboxCompilerOptions(config: PlaygroundConfig, monac
return settings
}

export const compilerOptionsFromLocation = (options: CompilerOptions, params: Map<string, any>) => {
const defaultCompilerOptions = {}

const urlDefaults = Object.entries(defaultCompilerOptions).reduce((acc: any, [key, value]) => {
/**
* Loop through all of the entries in the existing compiler options then compare them with the
* query params and return an object which is the changed settings via the query params
*/
export const getCompilerOptionsFromParams = (options: CompilerOptions, params: URLSearchParams): CompilerOptions => {
const urlDefaults = Object.entries(options).reduce((acc: any, [key, value]) => {
if (params.has(key)) {
const urlValue = params.get(key)
const urlValue = params.get(key)!

if (urlValue === 'true') {
acc[key] = true
} else if (urlValue === 'false') {
acc[key] = false
} else if (!isNaN(parseInt(urlValue, 10))) {
acc[key] = parseInt(params.get(key), 10)
acc[key] = parseInt(urlValue, 10)
}
}

Expand All @@ -72,31 +76,6 @@ export const compilerOptionsFromLocation = (options: CompilerOptions, params: Ma
return urlDefaults
}

export const getInitialCode = (location: Location) => {
if (location.hash.startsWith('#src')) {
const code = location.hash.replace('#src=', '').trim()
return decodeURIComponent(code)
}

if (location.hash.startsWith('#code')) {
const code = location.hash.replace('#code/', '').trim()
let userCode = LZString.decompressFromEncodedURIComponent(code)
// Fallback incase there is an extra level of decoding:
// https://gitter.im/Microsoft/TypeScript?at=5dc478ab9c39821509ff189a
if (!userCode) userCode = LZString.decompressFromEncodedURIComponent(decodeURIComponent(code))
return userCode
}

if (localStorage.getItem('playground-history')) {
return localStorage.getItem('playground-history')
}

return `
const message: string = 'hello world';
console.log(message);
`.trim()
}

// http://stackoverflow.com/questions/1714786/ddg#1714899
function objectToQueryParams(obj: any) {
const str = []
Expand Down
31 changes: 31 additions & 0 deletions packages/sandbox/src/getInitialCode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import lzstring from './vendor/lzstring.min'

/**
* Grabs the sourcecode for an example from the query hash or local storage
* @param fallback if nothing is found return this
* @param location DI'd copy of document.location
*/
export const getInitialCode = (fallback: string, location: Location) => {
// Old school support
if (location.hash.startsWith('#src')) {
const code = location.hash.replace('#src=', '').trim()
return decodeURIComponent(code)
}

// New school support
if (location.hash.startsWith('#code')) {
const code = location.hash.replace('#code/', '').trim()
let userCode = lzstring.decompressFromEncodedURIComponent(code)
// Fallback incase there is an extra level of decoding:
// https://gitter.im/Microsoft/TypeScript?at=5dc478ab9c39821509ff189a
if (!userCode) userCode = lzstring.decompressFromEncodedURIComponent(decodeURIComponent(code))
return userCode
}

// Local copy fallback
if (localStorage.getItem('sandbox-history')) {
return localStorage.getItem('sandbox-history')!
}

return fallback
}
48 changes: 38 additions & 10 deletions packages/sandbox/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { createCompilerHost } from './createCompilerHost'
import { detectNewImportsToAcquireTypeFor } from './typeAcquisition'
import { sandboxTheme } from './theme'
import { TypeScriptWorker } from './tsWorker'
import { getDefaultSandboxCompilerOptions } from './compilerOptions'
import { getDefaultSandboxCompilerOptions, getCompilerOptionsFromParams } from './compilerOptions'
import lzstring from './vendor/lzstring.min'
import { supportedReleases } from './releases'
import { getInitialCode } from './getInitialCode'

type CompilerOptions = import('monaco-editor').languages.typescript.CompilerOptions
type Monaco = typeof import('monaco-editor')
Expand All @@ -24,6 +25,10 @@ export type PlaygroundConfig = {
monacoSettings?: import('monaco-editor').editor.IEditorOptions
/** Acquire types via type acquisition */
acquireTypes: boolean
/** Get the text via query params and local storage, useful when the editor is the main experience */
suppressAutomaticallyGettingDefaultText?: true
/** Suppress setting compiler options from the compiler flags from query params */
suppressAutomaticallyGettingCompilerFlags?: true
/** Logging system */
logger: { log: (...args: any[]) => void; error: (...args: any[]) => void }
} & (
Expand Down Expand Up @@ -85,8 +90,12 @@ export const createTypeScriptSandbox = (
const language = languageType(config)
const filePath = createFileUri(config, compilerDefaults, monaco)
const element = 'domID' in config ? document.getElementById(config.domID) : (config as any).elementToAppend
const model = monaco.editor.createModel(config.text, language, filePath)

const defaultText = config.suppressAutomaticallyGettingDefaultText
? config.text
: getInitialCode(config.text, document.location)

const model = monaco.editor.createModel(defaultText, language, filePath)
monaco.editor.defineTheme('sandbox', sandboxTheme)
monaco.editor.setTheme('sandbox')

Expand All @@ -101,23 +110,42 @@ export const createTypeScriptSandbox = (
? monaco.languages.typescript.javascriptDefaults
: monaco.languages.typescript.typescriptDefaults

// Grab types
if (config.acquireTypes) {
editor.onDidChangeModelContent(() => {
// In the future it'd be good to add support for an 'add many files'
const addLibraryToRuntime = (code: string, path: string) => {
defaults.addExtraLib(code, path)
config.logger.log(`[ATA] Adding ${path} to runtime`)
}
// In the future it'd be good to add support for an 'add many files'
const addLibraryToRuntime = (code: string, path: string) => {
defaults.addExtraLib(code, path)
config.logger.log(`[ATA] Adding ${path} to runtime`)
}

// Take the code from the editor right away
const code = editor.getModel()!.getValue()
detectNewImportsToAcquireTypeFor(code, addLibraryToRuntime, window.fetch.bind(window), config)

// Then update it when the model changes, perhaps this could be a debounced plugin instead in the future?
editor.onDidChangeModelContent(() => {
const code = editor.getModel()!.getValue()
detectNewImportsToAcquireTypeFor(code, addLibraryToRuntime, window.fetch.bind(window), config)
})
}

let compilerOptions = compilerDefaults
defaults.setCompilerOptions(compilerDefaults)
// Grab the compiler flags via the query params
let compilerOptions: CompilerOptions
if (!config.suppressAutomaticallyGettingCompilerFlags) {
const params = new URLSearchParams(location.search)
let queryParamCompilerOptions = getCompilerOptionsFromParams(compilerDefaults, params)
if (Object.keys(queryParamCompilerOptions).length)
config.logger.log('[Compiler] Found compiler options in query params: ', queryParamCompilerOptions)
compilerOptions = { ...compilerDefaults, ...queryParamCompilerOptions }
} else {
compilerOptions = compilerDefaults
}

config.logger.log('[Compiler] Set compiler options: ', compilerOptions)
defaults.setCompilerOptions(compilerOptions)

const updateCompilerSettings = (opts: CompilerOptions) => {
config.logger.log('[Compiler] Updating compiler options: ', opts)
compilerOptions = { ...opts, ...compilerOptions }
defaults.setCompilerOptions(opts)
}
Expand Down
19 changes: 11 additions & 8 deletions packages/typescriptlang-org/src/pages/play.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { withPrefix } from "gatsby"
import "./play.scss"
import { RenderExamples } from "../components/ShowExamples"

// This gets set by the playground
declare const playground: ReturnType<typeof import("typescript-playground").setupPlayground>

const Index = (props: any) => {
useEffect(() => {
const getLoaderScript = document.createElement('script');
Expand Down Expand Up @@ -109,7 +112,7 @@ markdown("OK")`
</nav>

<div className="ms-depth-4" style={{ backgroundColor: "white", margin: "1rem auto", padding: "2rem", paddingTop: "0", marginTop: "0" }}>
<h1 id="loader" style={{ textAlign: "center" }}>Loading</h1>
<h1 id="loader" style={{ textAlign: "center", height: "800px" }}>Loading</h1>
<div id="playground-container" style={{ display: "none" }}>
<div id="editor-container">
<div id="editor-toolbar" className="navbar-sub" >
Expand All @@ -124,16 +127,16 @@ markdown("OK")`
<li className="dropdown">
<a href="#" className="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Export <span className="caret"></span></a>
<ul className="dropdown-menu">
<li><a id="export-create-gh-issue" href="#" >Report GitHub issue on TypeScript</a></li>
<li><a id="export-create-gh-issue" href="#" onClick={() => playground.exporter.reportIssue()} >Report GitHub issue on TypeScript</a></li>
<li role="separator" className="divider"></li>
<li><a id="export-copy-issue-markdown" href="#" >Copy as Markdown Issue</a></li>
<li><a id="export-copy-markdown" href="#" >Copy as Markdown Link</a></li>
<li><a id="export-copy-markdown" href="#" >Copy as Markdown Link with Preview</a></li>
<li><a id="export-copy-issue-markdown" href="#" onClick={() => playground.exporter.copyAsMarkdownIssue()} >Copy as Markdown Issue</a></li>
<li><a id="export-copy-markdown" href="#" onClick={() => playground.exporter.copyForChat()} >Copy as Markdown Link</a></li>
<li><a id="export-copy-markdown" href="#" onClick={() => playground.exporter.copyForChatWithPreview()} >Copy as Markdown Link with Preview</a></li>
<li role="separator" className="divider"></li>
<li><a id="export-copy-markdown" href="#" >Open in TypeScript AST Viewer</a></li>
<li><a id="export-copy-markdown" href="#" onClick={() => playground.exporter.openInTSAST()} >Open in TypeScript AST Viewer</a></li>
<li role="separator" className="divider"></li>
<li><a id="export-open-code-sandbox" href="#">Open in CodeSandbox</a></li>
<li><a id="export-open-stackblitz" href="#" >Open in StackBlitz</a></li>
<li><a id="export-open-code-sandbox" href="#" onClick={() => playground.exporter.openProjectInCodeSandbox()}>Open in CodeSandbox</a></li>
<li><a id="export-open-stackblitz" href="#" onClick={() => playground.exporter.openProjectInStackBlitz()}>Open in StackBlitz</a></li>
</ul>
</li>
</ul>
Expand Down

0 comments on commit b33592f

Please sign in to comment.