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