editor first run
This commit is contained in:
180
Inspectron.PrintServer.TemplateEditor/wwwroot/app.css
Normal file
180
Inspectron.PrintServer.TemplateEditor/wwwroot/app.css
Normal file
@@ -0,0 +1,180 @@
|
||||
h1:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.editor-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
padding: 6px 8px;
|
||||
background: #2d2d2d;
|
||||
border-bottom: 1px solid #404040;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.toolbar-btn {
|
||||
padding: 4px 14px;
|
||||
background: #3c3c3c;
|
||||
color: #cccccc;
|
||||
border: 1px solid #555;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.toolbar-btn:hover {
|
||||
background: #505050;
|
||||
}
|
||||
|
||||
.toolbar-separator {
|
||||
width: 1px;
|
||||
background: #555;
|
||||
margin: 2px 6px;
|
||||
}
|
||||
|
||||
.json-indicator {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 2px 10px;
|
||||
background: #2b4a3e;
|
||||
color: #4EC9B0;
|
||||
border: 1px solid #3a6b57;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
max-width: 200px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.split-pane {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.pane {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.pane-editor {
|
||||
flex: 1;
|
||||
border-right: 1px solid #404040;
|
||||
}
|
||||
|
||||
.pane-preview {
|
||||
flex: 1;
|
||||
background: #1e1e1e;
|
||||
}
|
||||
|
||||
.pane-header {
|
||||
padding: 4px 10px;
|
||||
background: #252526;
|
||||
color: #888;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
border-bottom: 1px solid #404040;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#my-editor-id {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.preview-content {
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
color: #cccccc;
|
||||
}
|
||||
.valid.modified:not([type=checkbox]) {
|
||||
outline: 1px solid #26b050;
|
||||
}
|
||||
|
||||
.invalid {
|
||||
outline: 1px solid #e50000;
|
||||
}
|
||||
|
||||
.validation-message {
|
||||
color: #e50000;
|
||||
}
|
||||
|
||||
#blazor-error-ui {
|
||||
color-scheme: light only;
|
||||
background: lightyellow;
|
||||
bottom: 0;
|
||||
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
|
||||
box-sizing: border-box;
|
||||
display: none;
|
||||
left: 0;
|
||||
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#blazor-error-ui .dismiss {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 0.75rem;
|
||||
top: 0.5rem;
|
||||
}
|
||||
|
||||
.blazor-error-boundary {
|
||||
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
|
||||
padding: 1rem 1rem 1rem 3.7rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.blazor-error-boundary::after {
|
||||
content: "An error has occurred."
|
||||
}
|
||||
|
||||
.darker-border-checkbox.form-check-input {
|
||||
border-color: #929292;
|
||||
}
|
||||
|
||||
.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
|
||||
color: var(--bs-secondary-color);
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
|
||||
text-align: start;
|
||||
}
|
||||
|
||||
.status-bar-safe-area {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@supports (-webkit-touch-callout: none) {
|
||||
.status-bar-safe-area {
|
||||
display: flex;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
height: env(safe-area-inset-top);
|
||||
background-color: #f7f7f7;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.flex-column, .navbar-brand {
|
||||
padding-left: env(safe-area-inset-left);
|
||||
}
|
||||
}
|
||||
33
Inspectron.PrintServer.TemplateEditor/wwwroot/index.html
Normal file
33
Inspectron.PrintServer.TemplateEditor/wwwroot/index.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
|
||||
<title>Inspectron.PrintServer.TemplateEditor</title>
|
||||
<base href="/" />
|
||||
<link rel="stylesheet" href="app.css" />
|
||||
<link rel="stylesheet" href="Inspectron.PrintServer.TemplateEditor.styles.css" />
|
||||
<link rel="icon" href="data:,">
|
||||
<script src="_content/BlazorMonaco/jsInterop.js"></script>
|
||||
<script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
|
||||
<script src="_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
|
||||
<script src="receiptLanguage.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="status-bar-safe-area"></div>
|
||||
|
||||
<div id="app">Loading...</div>
|
||||
|
||||
<div id="blazor-error-ui" data-nosnippet>
|
||||
An unhandled error has occurred.
|
||||
<a href="." class="reload">Reload</a>
|
||||
<span class="dismiss">🗙</span>
|
||||
</div>
|
||||
|
||||
<script src="_framework/blazor.webview.js" autostart="false"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
158
Inspectron.PrintServer.TemplateEditor/wwwroot/receiptLanguage.js
Normal file
158
Inspectron.PrintServer.TemplateEditor/wwwroot/receiptLanguage.js
Normal file
@@ -0,0 +1,158 @@
|
||||
window.receiptLanguage = {
|
||||
_registered: false,
|
||||
|
||||
register: function () {
|
||||
if (this._registered) return;
|
||||
this._registered = true;
|
||||
|
||||
monaco.languages.register({ id: 'receipt-xml' });
|
||||
|
||||
monaco.languages.setLanguageConfiguration('receipt-xml', {
|
||||
comments: {
|
||||
blockComment: ['<!--', '-->']
|
||||
},
|
||||
brackets: [
|
||||
['<', '>'],
|
||||
['{{', '}}']
|
||||
],
|
||||
autoClosingPairs: [
|
||||
{ open: '<', close: '>' },
|
||||
{ open: '{{', close: '}}' },
|
||||
{ open: '"', close: '"' },
|
||||
{ open: "'", close: "'" }
|
||||
],
|
||||
surroundingPairs: [
|
||||
{ open: '<', close: '>' },
|
||||
{ open: '"', close: '"' },
|
||||
{ open: "'", close: "'" }
|
||||
]
|
||||
});
|
||||
|
||||
var knownElements = [
|
||||
'receipt', 'line', 'columns', 'row', 'col', 'separator',
|
||||
'cut', 'feed', 'table', 'foreach', 'if', 'else'
|
||||
];
|
||||
|
||||
monaco.languages.setMonarchTokensProvider('receipt-xml', {
|
||||
knownElements: knownElements,
|
||||
|
||||
tokenizer: {
|
||||
root: [
|
||||
// Expression open
|
||||
[/\{\{/, { token: 'delimiter.expression', next: '@expression' }],
|
||||
|
||||
// XML comment
|
||||
[/<!--/, { token: 'comment', next: '@comment' }],
|
||||
|
||||
// Closing tag
|
||||
[/<\//, { token: 'delimiter.tag', next: '@closingTag' }],
|
||||
|
||||
// Self-closing or opening tag
|
||||
[/</, { token: 'delimiter.tag', next: '@openingTag' }],
|
||||
|
||||
// Plain text
|
||||
[/[^<{]+/, 'text']
|
||||
],
|
||||
|
||||
expression: [
|
||||
[/\}\}/, { token: 'delimiter.expression', next: '@pop' }],
|
||||
[/\$index|\$first|\$last/, 'variable.special'],
|
||||
[/:[^}]+/, 'string.format'],
|
||||
[/[a-zA-Z_][\w]*(?:\.[a-zA-Z_][\w]*)*/, 'variable.property'],
|
||||
[/./, 'variable.property']
|
||||
],
|
||||
|
||||
openingTag: [
|
||||
// Match element name
|
||||
[/([a-zA-Z][\w-]*)/, {
|
||||
cases: {
|
||||
'@knownElements': { token: 'tag.element', next: '@tagAttributes' },
|
||||
'@default': { token: 'tag.unknown', next: '@tagAttributes' }
|
||||
}
|
||||
}],
|
||||
[/>/, { token: 'delimiter.tag', next: '@pop' }]
|
||||
],
|
||||
|
||||
closingTag: [
|
||||
[/([a-zA-Z][\w-]*)/, {
|
||||
cases: {
|
||||
'@knownElements': 'tag.element',
|
||||
'@default': 'tag.unknown'
|
||||
}
|
||||
}],
|
||||
[/>/, { token: 'delimiter.tag', next: '@pop' }],
|
||||
[/\s+/, '']
|
||||
],
|
||||
|
||||
tagAttributes: [
|
||||
// Self-closing
|
||||
[/\/>/, { token: 'delimiter.tag', next: '@popall' }],
|
||||
|
||||
// Close tag
|
||||
[/>/, { token: 'delimiter.tag', next: '@popall' }],
|
||||
|
||||
// Attribute name
|
||||
[/[a-zA-Z_][\w-]*/, 'attribute.name'],
|
||||
|
||||
// Equals sign
|
||||
[/=/, 'delimiter'],
|
||||
|
||||
// Quoted attribute values
|
||||
[/"/, { token: 'attribute.value.delimiter', next: '@attrValueDouble' }],
|
||||
[/'/, { token: 'attribute.value.delimiter', next: '@attrValueSingle' }],
|
||||
|
||||
// Whitespace
|
||||
[/\s+/, '']
|
||||
],
|
||||
|
||||
attrValueDouble: [
|
||||
[/\{\{/, { token: 'delimiter.expression', next: '@expression' }],
|
||||
[/"/, { token: 'attribute.value.delimiter', next: '@pop' }],
|
||||
[/[^"{]+/, 'attribute.value']
|
||||
],
|
||||
|
||||
attrValueSingle: [
|
||||
[/\{\{/, { token: 'delimiter.expression', next: '@expression' }],
|
||||
[/'/, { token: 'attribute.value.delimiter', next: '@pop' }],
|
||||
[/[^'{]+/, 'attribute.value']
|
||||
],
|
||||
|
||||
comment: [
|
||||
[/-->/, { token: 'comment', next: '@pop' }],
|
||||
[/./, 'comment']
|
||||
]
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
defineTheme: function () {
|
||||
monaco.editor.defineTheme('receipt-dark', {
|
||||
base: 'vs-dark',
|
||||
inherit: true,
|
||||
rules: [
|
||||
{ token: 'tag.element', foreground: '569CD6', fontStyle: 'bold' },
|
||||
{ token: 'tag.unknown', foreground: 'F44747' },
|
||||
{ token: 'attribute.name', foreground: '9CDCFE' },
|
||||
{ token: 'attribute.value', foreground: 'CE9178' },
|
||||
{ token: 'attribute.value.delimiter', foreground: 'CE9178' },
|
||||
{ token: 'delimiter.tag', foreground: '808080' },
|
||||
{ token: 'delimiter', foreground: '808080' },
|
||||
{ token: 'delimiter.expression', foreground: 'DCDCAA', fontStyle: 'bold' },
|
||||
{ token: 'variable.property', foreground: '4EC9B0' },
|
||||
{ token: 'variable.special', foreground: 'C586C0', fontStyle: 'italic' },
|
||||
{ token: 'string.format', foreground: 'D7BA7D' },
|
||||
{ token: 'comment', foreground: '6A9955', fontStyle: 'italic' },
|
||||
{ token: 'text', foreground: 'D4D4D4' }
|
||||
],
|
||||
colors: {}
|
||||
});
|
||||
},
|
||||
|
||||
getEditorContent: function (editorId) {
|
||||
var editor = blazorMonaco.editor.getEditorById(editorId);
|
||||
if (editor) {
|
||||
return editor.getValue();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user