markupeditor 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/bin/filetoolbar.css +28 -0
- package/bin/filetoolbar.js +126 -0
- package/bin/muedit.js +85 -0
- package/dist/custom-elements.json +4112 -0
- package/dist/markup-editor.js +25000 -0
- package/package.json +69 -0
- package/styles/markup.css +273 -0
- package/styles/markupeditor.css +3 -0
- package/styles/mirror.css +190 -0
- package/styles/toolbar.css +651 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Steven G. Harris
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img alt="The MarkupEditor logo" src="https://github.com/user-attachments/assets/c67b6aa0-2576-4a0b-81d0-229ee501b59d" width="96px" height="96px" >
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# MarkupEditor
|
|
6
|
+
|
|
7
|
+
The MarkupEditor consists of a web component and API for WYSIWYG HTML editing. The "source of truth" for the MarkupEditor is standard HTML,
|
|
8
|
+
styled using standard CSS. The MarkupEditor comes with a toolbar and hot key bindings to access its editing functionality. The toolbar
|
|
9
|
+
visibility and contents, as well as the key bindings, are configurable and extensible.
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
The web component makes embedding WYSIWYG editing as simple as:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
<markup-editor><h1>Hello, MarkupEditor!</h1></markup-editor>
|
|
17
|
+
<script src="markup-editor.js" type="module"></script>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Why
|
|
21
|
+
|
|
22
|
+
You or the consumers of your application need to edit more than just plain text. You want to be able to format and organize a document with
|
|
23
|
+
headers, lists, links, images, and perhaps tables, but you do not want to do that using Markdown or require that the consumers of your app
|
|
24
|
+
know anything about Markdown or HTML. The MarkupEditor is the solution. It can be used in any environment that supports a web view, from a
|
|
25
|
+
browser to a mobile or desktop app.
|
|
26
|
+
|
|
27
|
+
Like Markdown, the MarkupEditor keeps the focus on what you're writing, with a minimum of distractions. Like Markdown, it supports just enough
|
|
28
|
+
functionality to help you organize and format your writing to get your points across effectively. Unlike Markdown, the MarkupEditor's WYSIWYG
|
|
29
|
+
approach means you always see what you're writing presented properly as you write it, instead of dealing with the distractions of composing
|
|
30
|
+
text with embedded notations and the uncertainty of how that text is later translated to HTML and presented.
|
|
31
|
+
|
|
32
|
+
## Features
|
|
33
|
+
|
|
34
|
+
The MarkupEditor's standard editing features are generally limited to what
|
|
35
|
+
[Github Flavored Markdown](https://github.github.com/gfm/) supports. It does, however, have support
|
|
36
|
+
for some functionality beyond that baseline. As a WYSIWYG editor, it supports the kind of functionality that
|
|
37
|
+
even non-developers expect when they edit a document, like image resizing and search.
|
|
38
|
+
|
|
39
|
+
* Customizable and extensible toolbar providing access to all editing features, auto-sized to width.
|
|
40
|
+
* Customizable key mappings for hot-key access to editing features.
|
|
41
|
+
* Customizable ordering of toolbar contents.
|
|
42
|
+
* Customizable icons for toolbar.
|
|
43
|
+
* Paragraph styles corresponding to P, H1-H6, and `CODE`.
|
|
44
|
+
* Bold, italic, underline, strikethrough, subscript, superscript, and code text formatting.
|
|
45
|
+
* Insert and edit links, images (local and https src), and tables.
|
|
46
|
+
* Bulleted and numbered lists.
|
|
47
|
+
* Indent/outdent.
|
|
48
|
+
* Comprehensive undo/redo.
|
|
49
|
+
* Search.
|
|
50
|
+
* Image resizing using gestures.
|
|
51
|
+
* Table editing: visually select table size, add/remove row/column/header, border options.
|
|
52
|
+
|
|
53
|
+
The API provides hooks for callbacks as your document changes, as well as access to the edited HTML
|
|
54
|
+
so that you can save contents in a way that makes sense in your own context.
|
|
55
|
+
|
|
56
|
+
The web component and customization capabilities allow the MarkupEditor to be embedded in different
|
|
57
|
+
environments, such as an Electron-based [desktop editing app](https://github.com/stevengharris/markupeditor-desktop),
|
|
58
|
+
a [Swift library for WYSIWYG editing](https://github.com/stevengharris/MarkupEditor), and
|
|
59
|
+
a [VSCode extension](https://github.com/stevengharris/markupeditor-vs).
|
|
60
|
+
|
|
61
|
+
## Try
|
|
62
|
+
|
|
63
|
+
You can try the MarkupEditor out right from the [project web site](https://stevengharris.github.io/markupeditor-base/). The web site has all
|
|
64
|
+
the information you need to use the MarkupEditor in your application.
|
|
65
|
+
|
|
66
|
+
## Install
|
|
67
|
+
|
|
68
|
+
Clone the repository.
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
git clone https://github.com/stevengharris/markupeditor-base.git
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
You need node/npm installed. Install the dependencies.
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
$ cd markupeditor-base/
|
|
78
|
+
$ npm install
|
|
79
|
+
|
|
80
|
+
added 265 packages, and audited 266 packages in 9s
|
|
81
|
+
|
|
82
|
+
70 packages are looking for funding
|
|
83
|
+
run `npm fund` for details
|
|
84
|
+
|
|
85
|
+
found 0 vulnerabilities
|
|
86
|
+
$
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Build the project.
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
$ npm run build
|
|
93
|
+
|
|
94
|
+
> markupeditor@0.9.0 build
|
|
95
|
+
> rollup -c
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
src/main.js → dist/markup-editor.js...
|
|
99
|
+
created dist/markup-editor.js in 300ms
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The installation identifies `muedit` in the package.json `bin` property. You can open the editor on a doc using node.js with
|
|
103
|
+
the `muedit` command, providing a filename to edit (and optionally a port for node.js). You can use the demo.html file that
|
|
104
|
+
is part of the docs:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
$ muedit docs/demo/demo.html
|
|
108
|
+
Server listening at http://localhost:3000
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Then open http://localhost:3000 in your browser. The port can be passed to node as `--port <number>`. Alternatively, you
|
|
112
|
+
can run node directly as `node ./bin/muedit.js docs/demo/demo.html`.
|
|
113
|
+
|
|
114
|
+
## Local Documentation
|
|
115
|
+
|
|
116
|
+
You can also set up the web site docs to test and view locally. The `npm run docs` command copies the `markup-editor.js`
|
|
117
|
+
file and css (which may have changed locally as you develop) to the proper position in the `docs` directory and then runs
|
|
118
|
+
`jsdoc` to produce the API documentation. The API documentation contents and options are defined in `jsdoc.json` and
|
|
119
|
+
use a customized template, `apilayout.tmpl`. The `apireadme.md` in the `docs/resources` directory is displayed as the
|
|
120
|
+
contents of the "home" page.
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
$ npm run docs
|
|
124
|
+
|
|
125
|
+
> markupeditor@0.9.0 predocs
|
|
126
|
+
> sh predocs.sh && jsdoc -c jsdoc.json
|
|
127
|
+
|
|
128
|
+
Updating ./docs dependencies...
|
|
129
|
+
cp -f ./dist/markup-editor.js ./docs/src/markup-editor.js
|
|
130
|
+
cp -f ./styles/markupeditor.css ./docs/styles/markupeditor.css
|
|
131
|
+
cp -f ./styles/markup.css ./docs/styles/markup.css
|
|
132
|
+
cp -f ./styles/mirror.css ./docs/styles/mirror.css
|
|
133
|
+
cp -f ./styles/toolbar.css ./docs/styles/toolbar.css
|
|
134
|
+
|
|
135
|
+
> markupeditor@0.9.0 docs
|
|
136
|
+
> node ./docs/index.js
|
|
137
|
+
|
|
138
|
+
Server listening at http://localhost:3000
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
What http://localhost:3000 shows now is the contents hosted at https://stevengharris.github.io/markupeditor-base.
|
|
142
|
+
|
|
143
|
+
Since the project web site is hosted on GitHub Pages, this process makes it simple to keep the docs up-to-date and
|
|
144
|
+
test the web site locally.
|
|
145
|
+
|
|
146
|
+
## Resources
|
|
147
|
+
|
|
148
|
+
Refer to the [Resources](https://stevengharris.github.io/markupeditor-base/#resources) section of the [project web site](https://stevengharris.github.io/markupeditor-base/)
|
|
149
|
+
for links to documentation, demos, and other projects using the MarkupEditor.
|
|
150
|
+
|
|
151
|
+
## Acknowledgements
|
|
152
|
+
|
|
153
|
+
This project was originally delivered as a single JavaScript file within the [Swift MarkupEditor](https://github.com/stevengharris/MarkupEditor),
|
|
154
|
+
a project that provides WYSIWYG editing functionality to Swift UIKIt and iOS SwiftUI developers. Eventually, the Swift project moved to using the
|
|
155
|
+
excellent [ProseMirror](https://prosemirror.net) project for all of the heavy lifting of WYSIWYG editing in its web view backend. With the formalization
|
|
156
|
+
of this MarkupEditor base project, the Swift project now depends on `markupeditor-base` which in turn depends on ProseMirror. The MarkupEditor base
|
|
157
|
+
project can then be re-used, within a [desktop editing app](https://github.com/stevengharris/markupeditor-desktop) or
|
|
158
|
+
[VSCode extension](https://github.com/stevengharris/markupeditor-vs).
|
|
159
|
+
|
|
160
|
+
To quote from the ProseMirror site:
|
|
161
|
+
|
|
162
|
+
> ProseMirror is [open source](https://github.com/ProseMirror/prosemirror/blob/master/LICENSE), and you are legally free to use it commercially. Yet, writing, maintaining, supporting, and setting up infrastructure for such a project takes a lot of work and energy. Therefore...
|
|
163
|
+
|
|
164
|
+
> **If you are using ProseMirror to make profit, there is a social expectation that you help fund its maintenance. [Start here](http://marijnhaverbeke.nl/fund/).**
|
|
165
|
+
|
|
166
|
+
I encourage MarkupEditor users to take these statements to heart and support ProseMirror directly if you use the MarkupEditor to make a profit.
|
|
167
|
+
|
|
168
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* Base toast styling */
|
|
2
|
+
.toast {
|
|
3
|
+
font-size: 1rem;
|
|
4
|
+
white-space: nowrap;
|
|
5
|
+
text-overflow: ellipsis;
|
|
6
|
+
display: inline-block;
|
|
7
|
+
visibility: hidden; /* Hidden by default */
|
|
8
|
+
background-color: #333;
|
|
9
|
+
color: #fff;
|
|
10
|
+
text-align: center;
|
|
11
|
+
border-radius: 2px;
|
|
12
|
+
padding: 4px;
|
|
13
|
+
margin-bottom: 8px; /* Spacing between multiple toasts */
|
|
14
|
+
opacity: 0;
|
|
15
|
+
transition: opacity 0.5s, visibility 0.5s;
|
|
16
|
+
}
|
|
17
|
+
@media (prefers-color-scheme: dark) {
|
|
18
|
+
.toast {
|
|
19
|
+
background: #fff;
|
|
20
|
+
color: #333;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* Class added by JavaScript to show the toast */
|
|
25
|
+
.toast.show {
|
|
26
|
+
visibility: visible;
|
|
27
|
+
opacity: 1;
|
|
28
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { MU } from "/markup-editor.js"
|
|
2
|
+
|
|
3
|
+
/** A class holding the command items and functionality for a File toolbar that is prepended to the MarkupEditor toolbar */
|
|
4
|
+
class FileToolbar {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.menuItems = this.buildMenuItems()
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** SVG defining icons by key, obtained from https://fonts.google.com/icons under https://openfontlicense.org license. */
|
|
10
|
+
icons = {
|
|
11
|
+
// <span class="material-symbols-outlined">note_add</span>
|
|
12
|
+
new: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M440-240h80v-120h120v-80H520v-120h-80v120H320v80h120v120ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg>',
|
|
13
|
+
// <span class="material-symbols-outlined">file_open</span>
|
|
14
|
+
open: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v240h-80v-200H520v-200H240v640h360v80H240Zm638 15L760-183v89h-80v-226h226v80h-90l118 118-56 57Zm-638-95v-640 640Z"/></svg>',
|
|
15
|
+
// <span class="material-symbols-outlined">file_copy</span>
|
|
16
|
+
copy: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M744-192H312q-29 0-50.5-21.5T240-264v-576q0-29 21.5-50.5T312-912h312l192 192v456q0 29-21.5 50.5T744-192ZM576-672v-168H312v576h432v-408H576ZM168-48q-29 0-50.5-21.5T96-120v-552h72v552h456v72H168Zm144-792v195-195 576-576Z"/></svg>'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Return an array of MenuItems */
|
|
20
|
+
buildMenuItems() {
|
|
21
|
+
let newItem = MU.cmdItem(
|
|
22
|
+
this.newDocument.bind(this),
|
|
23
|
+
{
|
|
24
|
+
enable: () => { return true },
|
|
25
|
+
title: 'New document',
|
|
26
|
+
icon: this.icons.new
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
let openItem = MU.cmdItem(
|
|
30
|
+
this.openDocument.bind(this),
|
|
31
|
+
{
|
|
32
|
+
enable: () => { return true },
|
|
33
|
+
title: 'Open document',
|
|
34
|
+
icon: this.icons.open
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
let copyItem = MU.cmdItem(
|
|
38
|
+
this.copyHTML.bind(this),
|
|
39
|
+
{
|
|
40
|
+
enable: () => { return true },
|
|
41
|
+
title: 'Copy HTML',
|
|
42
|
+
icon: this.icons.copy,
|
|
43
|
+
// Use a callback to provide a "toast" indicating the copy worked
|
|
44
|
+
callback: this.notifyCopy.bind(this)
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
return [newItem, openItem, copyItem]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
newDocument(state, dispatch, view) {
|
|
51
|
+
MU.setActiveView(view)
|
|
52
|
+
MU.emptyDocument()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Open the picker as listen for changes in the input element */
|
|
56
|
+
openDocument(state, dispatch, view) {
|
|
57
|
+
MU.setActiveView(view)
|
|
58
|
+
let picker = document.getElementById('docpicker');
|
|
59
|
+
picker.addEventListener('change', this.loadDocument.bind(this));
|
|
60
|
+
picker.showPicker();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* When the user selects an HTML file from the picker, get its contents, update the document in
|
|
65
|
+
* the editor.
|
|
66
|
+
*
|
|
67
|
+
* Note: Because we don't have access to an actual file picker or any way to determine what local
|
|
68
|
+
* directory the file resides in, there is no way to set "base" for the document. This means that
|
|
69
|
+
* local images will almost certainly not load and will generate 404s. Refer to the markupeditor-desktop
|
|
70
|
+
* for an electron example that supports the file system natively.
|
|
71
|
+
*/
|
|
72
|
+
loadDocument() {
|
|
73
|
+
let picker = document.getElementById('docpicker');
|
|
74
|
+
picker.removeEventListener('change', this.loadDocument.bind(this));
|
|
75
|
+
let files = picker.files;
|
|
76
|
+
if (files) {
|
|
77
|
+
let file = files[0]
|
|
78
|
+
const reader = new FileReader();
|
|
79
|
+
reader.addEventListener('load', (event) => {
|
|
80
|
+
const text = event.target.result; // The file contents
|
|
81
|
+
MU.setHTML(text)
|
|
82
|
+
});
|
|
83
|
+
reader.readAsText(file);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async copyHTML(state, dispatch, view) {
|
|
88
|
+
MU.setActiveView(view)
|
|
89
|
+
const text = MU.getHTML();
|
|
90
|
+
try {
|
|
91
|
+
await navigator.clipboard.writeText(text).then(() => { return })
|
|
92
|
+
} catch (err) {
|
|
93
|
+
console.error('Failed to copy: ', err);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Briefly add/remove `toast` class to the `menuItem` to display a "toast" notification.
|
|
99
|
+
*
|
|
100
|
+
* The filetoolbar.css defines the CSS using `userstyle` set in muedit.js.
|
|
101
|
+
*
|
|
102
|
+
* @param {HTMLSpanElement} menuItem
|
|
103
|
+
*/
|
|
104
|
+
notifyCopy(_ , menuItem) {
|
|
105
|
+
const toast = document.createElement("div");
|
|
106
|
+
toast.classList.add("toast");
|
|
107
|
+
toast.innerText = "Copied HTML"
|
|
108
|
+
|
|
109
|
+
menuItem.appendChild(toast);
|
|
110
|
+
|
|
111
|
+
// Show the toast
|
|
112
|
+
setTimeout(() => {
|
|
113
|
+
toast.classList.add("show");
|
|
114
|
+
}, 10); // Small delay to trigger CSS transition/animation
|
|
115
|
+
|
|
116
|
+
// Automatically hide and remove the toast after a few seconds
|
|
117
|
+
setTimeout(() => {
|
|
118
|
+
toast.classList.remove("show");
|
|
119
|
+
toast.remove();
|
|
120
|
+
}, 1500); // Toast visible for 1.5 seconds
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** By registering the augmentation, we can reference it by name in the <markup-editor> element toolbar attribute */
|
|
126
|
+
MU.registerAugmentation(new FileToolbar())
|
package/bin/muedit.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A script to run with node.js to open the MarkupEditor on an HTML file (or empty)
|
|
5
|
+
*/
|
|
6
|
+
import {argv} from 'node:process'
|
|
7
|
+
import {parseArgs} from 'node:util'
|
|
8
|
+
import express from 'express'
|
|
9
|
+
import path from 'node:path'
|
|
10
|
+
|
|
11
|
+
const __dirname = import.meta.dirname
|
|
12
|
+
|
|
13
|
+
const app = express()
|
|
14
|
+
|
|
15
|
+
const options = {
|
|
16
|
+
'port': {
|
|
17
|
+
type: 'string',
|
|
18
|
+
default: '3000'
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
var { values, positionals } = parseArgs({ argv, options, allowPositionals: true })
|
|
24
|
+
} catch {
|
|
25
|
+
values = []
|
|
26
|
+
positionals = []
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if ((values.length > 1) || (!values.port) || (positionals.length > 1)) {
|
|
30
|
+
console.log('Usage: muedit [--port number] [<filename>]')
|
|
31
|
+
} else {
|
|
32
|
+
let port = parseInt(values.port)
|
|
33
|
+
let filename = (positionals.length > 0) ? positionals[0] : null
|
|
34
|
+
let filenameAttribute = (filename) ? `filename="${filename}"` : '' // Empty for a new document
|
|
35
|
+
// Note that `base` is set to the filename path automatically
|
|
36
|
+
let placeholder = 'Edit document...'
|
|
37
|
+
|
|
38
|
+
// The web component is always located relative to node's `__dirname`,
|
|
39
|
+
// the location where muedit.js resides, which `app.use(express.static(__dirname))`
|
|
40
|
+
// ensures is available no matter what `process.cwd()` is.
|
|
41
|
+
let webcomponent = `/markup-editor.js`
|
|
42
|
+
|
|
43
|
+
// Allow references to dist from bin to work in index.html, to load the web component
|
|
44
|
+
app.use(express.static(path.join(__dirname, "../dist")))
|
|
45
|
+
|
|
46
|
+
// Allow the userscript and userstyles to load
|
|
47
|
+
app.use(express.static(__dirname))
|
|
48
|
+
|
|
49
|
+
// Allow the relative references inside of the edited document to work
|
|
50
|
+
app.use(express.static(`${process.cwd()}/`, {index: false}))
|
|
51
|
+
|
|
52
|
+
// For parsing application/json
|
|
53
|
+
app.use(express.json())
|
|
54
|
+
|
|
55
|
+
// Load when loading http://localhost:${port}
|
|
56
|
+
app.get('/', (req, res) => {
|
|
57
|
+
res.send(
|
|
58
|
+
`
|
|
59
|
+
<!DOCTYPE html>
|
|
60
|
+
<html lang="en">
|
|
61
|
+
<head>
|
|
62
|
+
<title>${filename ?? "MarkupEditor"}</title>
|
|
63
|
+
<meta name="viewport" charset="utf-8" content="width=device-width, initial-scale=1.0">
|
|
64
|
+
</head>
|
|
65
|
+
<body>
|
|
66
|
+
<markup-editor
|
|
67
|
+
placeholder="${placeholder}"
|
|
68
|
+
${filenameAttribute}
|
|
69
|
+
userscript="/filetoolbar.js"
|
|
70
|
+
userstyle="/filetoolbar.css"
|
|
71
|
+
prepend="FileToolbar"
|
|
72
|
+
>
|
|
73
|
+
</markup-editor>
|
|
74
|
+
<input id="docpicker" type="file" accept=".html" style="display: none">
|
|
75
|
+
<script src="${webcomponent}" type="module"></script>
|
|
76
|
+
</body>
|
|
77
|
+
</html>
|
|
78
|
+
`
|
|
79
|
+
)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
app.listen(port, () => {
|
|
83
|
+
console.log(`Server listening at http://localhost:${port}`)
|
|
84
|
+
})
|
|
85
|
+
}
|