mirror of https://github.com/sveltejs/svelte
parent
4b106d07d1
commit
4a142ea71e
@ -1,290 +0,0 @@
|
|||||||
<script context="module">
|
|
||||||
let codemirror_promise;
|
|
||||||
let _CodeMirror;
|
|
||||||
|
|
||||||
if (process.browser) {
|
|
||||||
codemirror_promise = import(/* webpackChunkName: "codemirror" */ './_codemirror.js');
|
|
||||||
|
|
||||||
codemirror_promise.then(mod => {
|
|
||||||
_CodeMirror = mod.default;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { onMount, beforeUpdate, createEventDispatcher } from 'svelte';
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
|
||||||
|
|
||||||
export let mode;
|
|
||||||
export let code;
|
|
||||||
export let readonly = false;
|
|
||||||
export let error = null;
|
|
||||||
export let errorLoc = null;
|
|
||||||
export let warningCount = 0;
|
|
||||||
export let flex = false;
|
|
||||||
export let lineNumbers = true;
|
|
||||||
export let tab = true;
|
|
||||||
|
|
||||||
let w;
|
|
||||||
let h;
|
|
||||||
|
|
||||||
export function resize() {
|
|
||||||
editor.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
const modes = {
|
|
||||||
json: {
|
|
||||||
name: 'javascript',
|
|
||||||
json: true
|
|
||||||
},
|
|
||||||
handlebars: {
|
|
||||||
name: 'handlebars',
|
|
||||||
base: 'text/html'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const refs = {};
|
|
||||||
let editor;
|
|
||||||
let updating = false;
|
|
||||||
let marker;
|
|
||||||
let error_line;
|
|
||||||
let destroyed = false;
|
|
||||||
let CodeMirror;
|
|
||||||
|
|
||||||
$: if (CodeMirror) {
|
|
||||||
createEditor(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
$: if (editor && !updating && code != null) {
|
|
||||||
updating = true;
|
|
||||||
editor.setValue(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
$: if (editor && w && h) {
|
|
||||||
editor.refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
$: {
|
|
||||||
if (marker) marker.clear();
|
|
||||||
|
|
||||||
if (errorLoc) {
|
|
||||||
const line = errorLoc.line - 1;
|
|
||||||
const ch = errorLoc.column;
|
|
||||||
|
|
||||||
marker = editor.markText({ line, ch }, { line, ch: ch + 1 }, {
|
|
||||||
className: 'error-loc'
|
|
||||||
});
|
|
||||||
|
|
||||||
error_line = line;
|
|
||||||
} else {
|
|
||||||
error_line = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let previous_error_line;
|
|
||||||
$: if (editor) {
|
|
||||||
if (previous_error_line != null) {
|
|
||||||
editor.removeLineClass(previous_error_line, 'wrap', 'error-line')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error_line && (error_line !== previous_error_line)) {
|
|
||||||
editor.addLineClass(error_line, 'wrap', 'error-line');
|
|
||||||
previous_error_line = error_line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
if (_CodeMirror) {
|
|
||||||
CodeMirror = _CodeMirror;
|
|
||||||
} else {
|
|
||||||
codemirror_promise.then(mod => {
|
|
||||||
CodeMirror = mod.default;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
destroyed = true;
|
|
||||||
if (editor) editor.toTextArea();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeUpdate(() => {
|
|
||||||
updating = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
function createEditor(mode) {
|
|
||||||
if (destroyed) return;
|
|
||||||
|
|
||||||
if (editor) {
|
|
||||||
editor.toTextArea();
|
|
||||||
}
|
|
||||||
|
|
||||||
const opts = {
|
|
||||||
lineNumbers,
|
|
||||||
lineWrapping: true,
|
|
||||||
indentWithTabs: true,
|
|
||||||
indentUnit: 2,
|
|
||||||
tabSize: 2,
|
|
||||||
value: code,
|
|
||||||
mode: modes[mode] || {
|
|
||||||
name: mode
|
|
||||||
},
|
|
||||||
readOnly: readonly
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!tab) opts.extraKeys = {
|
|
||||||
Tab: tab,
|
|
||||||
'Shift-Tab': tab
|
|
||||||
};
|
|
||||||
|
|
||||||
editor = CodeMirror.fromTextArea(refs.editor, opts);
|
|
||||||
|
|
||||||
editor.on('change', instance => {
|
|
||||||
if (!updating) {
|
|
||||||
updating = true;
|
|
||||||
code = instance.getValue();
|
|
||||||
dispatch('change', { value: code });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
editor.refresh();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.codemirror-container {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border: none;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codemirror-container :global(.CodeMirror) {
|
|
||||||
height: 100%;
|
|
||||||
/* background: var(--background); */
|
|
||||||
background: transparent;
|
|
||||||
font: 400 var(--code-fs)/1.7 var(--font-mono);
|
|
||||||
color: var(--base);
|
|
||||||
}
|
|
||||||
|
|
||||||
.codemirror-container.flex :global(.CodeMirror) {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codemirror-container.flex :global(.CodeMirror-lines) {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codemirror-container :global(.CodeMirror-gutters) {
|
|
||||||
padding: 0 1.6rem 0 .8rem;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codemirror-container .message {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 2.4rem;
|
|
||||||
left: 2.4rem;
|
|
||||||
z-index: 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codemirror-container :global(.error-loc) {
|
|
||||||
position: relative;
|
|
||||||
border-bottom: 2px solid #da106e;
|
|
||||||
}
|
|
||||||
|
|
||||||
.codemirror-container :global(.error-line) {
|
|
||||||
background-color: rgba(200, 0, 0, .05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading,
|
|
||||||
.error {
|
|
||||||
text-align: center;
|
|
||||||
color: #999;
|
|
||||||
font-weight: 400;
|
|
||||||
margin: 2.4rem 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loading {
|
|
||||||
background-color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
border: none;
|
|
||||||
padding: 4px 4px 4px 57px;
|
|
||||||
resize: none;
|
|
||||||
font-family: var(--font-mono);
|
|
||||||
font-size: 1.3rem;
|
|
||||||
line-height: 1.7;
|
|
||||||
user-select: none;
|
|
||||||
pointer-events: none;
|
|
||||||
color: #ccc;
|
|
||||||
tab-size: 2;
|
|
||||||
-moz-tab-size: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex pre {
|
|
||||||
padding: 0 0 0 4px;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex .loading {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
-----------------------------------------------
|
|
||||||
syntax-highlighting [prism]
|
|
||||||
NOTE
|
|
||||||
- just started to transfer colors from prism to codemirror
|
|
||||||
-----------------------------------------------
|
|
||||||
-->
|
|
||||||
<div class='codemirror-container' class:flex bind:offsetWidth={w} bind:offsetHeight={h}>
|
|
||||||
<textarea
|
|
||||||
tabindex='2'
|
|
||||||
bind:this={refs.editor}
|
|
||||||
readonly
|
|
||||||
value={code}
|
|
||||||
></textarea>
|
|
||||||
|
|
||||||
{#if error}
|
|
||||||
<p class='error message'>
|
|
||||||
{#if error.loc}
|
|
||||||
<strong>
|
|
||||||
{#if error.filename}
|
|
||||||
<span
|
|
||||||
class='filename'
|
|
||||||
on:click="{() => dispatch('navigate', { filename: error.filename })}"
|
|
||||||
>{error.filename}</span>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
({error.loc.line}:{error.loc.column})
|
|
||||||
</strong>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{error.message}
|
|
||||||
</p>
|
|
||||||
{:else if warningCount > 0}
|
|
||||||
<p class='warning message'>
|
|
||||||
Compiled, but with {warningCount} {warningCount === 1 ? 'warning' : 'warnings'} — check the console for details
|
|
||||||
</p>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
{#if !CodeMirror}
|
|
||||||
<pre style="position: absolute; left: 0; top: 0"
|
|
||||||
>{code}</pre>
|
|
||||||
|
|
||||||
<p class='loading message'>loading editor...</p>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
Loading…
Reference in new issue