首页 > 其他分享 >ace markdown editor 原生web components

ace markdown editor 原生web components

时间:2024-08-21 10:08:27浏览次数:12  
标签:web markdown ace src content editor shadowRoot

src/index.html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <ace-markdown></ace-markdown>
    <ace-markdown></ace-markdown>
    <script type="module" src="./ace.markdown.ts"></script>
</body>

</html>

src/ace.markdown.ts:

import ace from "ace-builds/src-min-noconflict/ace.js";
import { marked } from "marked";

class AceMarkdown extends HTMLElement {
	attatched = false;
	containerElement!: HTMLDivElement;
	content = "# Hello world";
	private editor!: any;
	editorElement!: HTMLDivElement;
	fullElement!: HTMLButtonElement;
	fullscreen = false;
	previewerElement!: HTMLDivElement;
	saveElement!: HTMLButtonElement;

	connectedCallback() {
		if (!this.attatched) {
			this.attatched = true;

			this.containerElement = this.shadowRoot?.querySelector("#container") as HTMLDivElement;
			this.editorElement = this.shadowRoot?.querySelector("#editor") as HTMLDivElement;
			this.fullElement = this.shadowRoot?.querySelector("#full") as HTMLButtonElement;
			this.previewerElement = this.shadowRoot?.querySelector("#previewer") as HTMLDivElement;
			this.saveElement = this.shadowRoot?.querySelector("#save") as HTMLButtonElement;

			ace.config.set("basePath", "/");
			const editor = ace.edit(this.editorElement, {
				// fontSize: "14px",
				mode: "ace/mode/markdown",
				// theme: "ace/theme/monokai",
				value: this.content,
				wrap: true,
			});
			this.editor = editor;
			editor.renderer.attachToShadowRoot(); // !!!important
			editor.on("input", () => {
				this.updatePreview();
			});
			this.updatePreview();

			this.fullElement.onclick = () => {
				this.fullscreenSwitch();
			}

			this.saveElement.onclick = () => {
				this.save();
			}
		}
	}

	constructor() {
		super();
		this.attachShadow({ mode: "open" });
		this.render();
	}

	fullscreenIcon() {
		return this.fullscreen ? "-" : "+";
	}

	fullscreenSwitch() {
		this.fullscreen = !this.fullscreen;
		if (this.fullscreen) {
			this.containerElement.requestFullscreen();
			this.containerElement.style.height = "100vh";
		} else {
			document.exitFullscreen();
			this.containerElement.style.height = "40vh";
		}
	}

	render() {
		if (this.shadowRoot) {
			this.shadowRoot.innerHTML = `<div id="container" style="height: 40vh">
			<div>
				<div style="display: flex; justify-content: end">
					<button id="save">下载</button>
					<button id="full" title="全屏/还原">${this.fullscreenIcon()}</button>
				</div>
			</div>
			<div style="display: flex; height: 100%">
				<div style="flex: 50%">
					<div id="editor" style="width: 100%; height: 100%;">${this.content}</div>
				</div>
				<div style="flex: 50%">
					<div id="previewer" style="width: 100%; height: 100%; overflow: auto"></div>
				</div>
			</div>
		</div>`;
		}
	}

	save() {
		const fileParts = [this.content];
		const blob = new Blob(fileParts, { type: "text/plain" });
		const a = document.createElement("a");
		a.href = URL.createObjectURL(blob);
		a.download = "paper.md";
		document.body.appendChild(a);
		a.click();
		document.body.removeChild(a);
	}

	updatePreview() {
		this.content = this.editor.getValue();
		this.previewerElement.innerHTML = marked(this.content).toString();
	}
}

customElements.define("ace-markdown", AceMarkdown);

declare global {
	interface HTMLElementTagNameMap {
		"ace-markdown": AceMarkdown;
	}
}

justfile:

build:
    #!/usr/bin/env bash
    rm -rf dist
    parcel build ./src/**.html --public-url . --no-source-maps
    cp node_modules/ace-builds/src-min-noconflict/mode-markdown.js dist/
    cp node_modules/ace-builds/src-min-noconflict/theme-monokai.js dist/

标签:web,markdown,ace,src,content,editor,shadowRoot
From: https://www.cnblogs.com/soarowl/p/18371019

相关文章

  • Web自动化测试-1
    1.前置配置1.1安装selenium在PyCharm的终端上输入命令:pipinstallselenium即可安装使用pipshowselenium来查看1.2浏览器的选择与配置浏览器 选择Edge,且在Edge中添加SelectorsHub-XPathHelper插件添加的具体操作请找相关资料以下从左到右分别是测试界面,控制台......
  • .net core web 启动过程(6)-ServiceProvider
    1 [MemberNotNull(nameof(_appServices))]privatevoidInitializeServiceProvider(){varservices=newServiceCollection();PopulateServiceCollection(services,_hostBuilderContext!,_hostingEnvironment!,......
  • Web端OA办公后台管理系统(使用AxureRP设计)思路与效果分享
    本期带来一套OA办公后台管理系统(办公一体化)的设计分享。本次的作品设计,使用AxureRP软件。一套实用的后台OA系统,一定是功能强大、能覆盖常用功能的。本次分享的系统,包含组织、员工管理、考勤、薪资、社保公积金、绩效、招聘、审批、会议室预定、车辆申请、新闻发布、公告管理、合......
  • 036、Vue3+TypeScript基础,路由中使用replace不让前进后退
    01、代码如下:<template><divclass="app"><h2class="title">App.Vue路由测试</h2><!--导航区--><divclass="navigate"><router-linkreplaceto="/Home"class="nav......
  • webpack 热更新实现原理
    修改entry配置首先通过启动webpack-dev-server会修改webpack.config.js的entry配置,新增两个入口文件:webpack-dev-server/client/index.jswebpack/hot/dev-server.jswebpack-dev-server/client/index.js包含的是客户端向服务端通信的相关代码。webpack/hot/dev-s......
  • 学习 node.js 六 Markdown 转为 html,zlib
    目录Markdown转为html安装ejs语法标签含义 1.纯文本标签2.输出经过HTML转义的内容3.输出非转义的内容(原始内容)markedbrowserSynczlibgzipdeflategzip和deflate区别http请求压缩 Markdown转为html什么是markdown?Markdown是一种轻量级标记......
  • web的发展历史,互联网和万维网的关系
    OpenSNN开思通智网,官网地址:https://w3.opensnn.com/2024年8月份"O站创作者招募计划"快来O站写文章,千元大奖等你来拿!“一起来O站,玩转AGI!”web的发展历史Web(万维网,WorldWideWeb)的发展历史是一段非常重要的技术进步和社会变革的历程。以下是Web发展的关键阶段:1.Web的诞生......
  • web的发展历史,互联网和万维网的关系
    OpenSNN开思通智网,官网地址:https://w3.opensnn.com/2024年8月份“O站创作者招募计划”快来O站写文章,千元等你来拿!“一起来O站,玩转AGI!”web的发展历史Web(万维网,WorldWideWeb)的发展历史是一段非常重要的技术进步和社会变革的历程。以下是Web发展的关键阶段:1.Web的......
  • 知识图谱——CiteSpace梳理学术脉络
    CiteSpace是一款强大的可视化分析软件,专门用于分析和可视化科学文献中的引文网络,以帮助识别科学领域的知识结构、研究前沿和发展趋势。下面我将详细介绍如何使用CiteSpace进行学术脉络梳理,并给出一个具体的例子。CiteSpace简介CiteSpace是一款免费的软件,它基于Java开发,可以用......
  • [Web Component] using `part` to allow applying styling from outside the shadow D
    Let'ssaywehaveawebcomponent: import{getProductById}from"../services/Menu.js";import{addToCart}from"../services/Order.js";exportdefaultclassDetailsPageextendsHTMLElement{constructor(){super();......