WebGL Tutorial
and more

LiveEditor Test

General

aaa
bbb
div { border: 1px solid gray; }
let container = document.getElementsByTagName('div')[0]; let div = document.createElement('div'); div.textContent = 'ccc'; container.appendChild(div);

CSS Grid Tutorial

Game Title
Score
Stats
Board
Controls
div.container { display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto 1fr auto; background: repeating-linear-gradient(45deg, #333333 0, #333333 5%, #4f4f4f 0, #4f4f4f 50%) 0 / 10px 10px; } #title {grid-column: 1; grid-row: 1;} #score {grid-column: 1; grid-row: 3;} #stats {grid-column: 1; grid-row: 2; align-self: start;} #board {grid-column: 2; grid-row: 1 / span 2;} #controls {grid-column: 2; grid-row: 3; justify-self: center;} div.container div { border: 1px solid gray; padding: 0.5em; background-color: #333; }
console.log('Hello');

取消默认的CSS设置

默认的CSS设置了以下的样式:

html, body { margin: 0; padding: 0; } body { color: #ACB7C4; background-color: #2B2B2B; }

若想取消以上默认设置,可加上一个no-default-style的属性:

...

这避免了在每个实例组件中通过更详细的语法来覆盖原有样式,客户端使用更加方便。

支持自定义CSS

A
B
C

观察上面的CSS标签页,里面并无任何内容,但运行后,发现边框、字体颜色及间距均有设置。LiveEdtor可通过result-default-css属性支持自定义的CSS设置。

...

这样,当我们需要为多个LiveEditor设置相同的CSS样式时,与其每次都在CSS标签页中重复设置,不如将这些相同的设置放在一个外部的CSS文件中,然后通过设置LiveEditor的result-default-css属性即可达到目的。

Loading from Files

以下是一个独立的文件src.html

<!DOCTYPE html> <html> <head> <title>Src</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> canvas { border: 1px solid gray; } </style> <script> let canvas = document.querySelector('canvas'); let ctx = canvas.getContext('2d'); ctx.strokeStyle = 'yellow'; ctx.strokeRect(0, 0, 50, 50); </script> </head> <body> <canvas></canvas> <p>The element above is a canvas.</p> </body> </html>

将上面的文件相应部分都分别提取出来放置至LiveEditor中:

效果:

这功能很酷,一是无需手工编写额外的代码,二是避免了不同步的问题,三是将一个可直接运行的网页文件立即转换为LiveEditor,可用于调试及演示的目的。

定制JavaScript代码

如果同一页面下的多个LiveEditor都用到同样的一段JavaScript代码,与其各自重复编写这样的代码,不如将其分离出来。共有2种方式。

第一种方法是通过创建一个CJS(common JavaScript)标签,将这些辅助性的JavaScript代码放在其中:

showMsg();
function showMsg() { console.log('Hello'); }

在运行时,放在CJS标签中的代码可被JS标签中的代码访问。

showMsg();
function showMsg() { console.log('Hello'); }

上面,在CJS标签中声明了一个名为showMsg的函数,而JS标签中的代码直接予以调用。

而如果CJS标签中的代码很长,则可通过第二种方式,为cjs-file属性指定一个外部JavaScript文件。

showMsg();

showMsg();

将调用者的相对路径转换为绝对路径

如果某个CSS文件中引用了相对路径的URL

#aDiv::after { content: url("./images/sun.svg"); ... }

LiveEditor是全局共享的,在其路径下肯定没有此图像文件。因此需要将上面相对于LiveEditor的相对路径转换为调用者的绝对路径。

LiveEditorapplyCSSFromTab方法对此进行了转换:

async applyCSSFromTab(doc, cssContent) { cssContent = cssContent.replaceAll(/(url\(")(.+)("\))/g, (match, p1, p2, p3) => { let newURL = new URL(p2, window.location); return p1 + newURL.pathname + p3; }); ... }

借用windowlocation,创建一个绝对路径的URL,再调用String的有回调函数版本的replaceAll方法,便捷地进行了转换。

钩子方法

为支持子类的灵活配置,LiveEditor7个钩子方法。

doOnSetupDivs(ctrlDiv, resultDiv, consoleDiv) { } doAfterRunClicked(iframe) { } doAfterApplyHTMLFromTab(doc) { } doBeforeApplyJSFromTab(doc, resultDiv) { return ''; } doOnSetupIframeTemplateSrc(iframe) { return '/js/esm/web-widgets/live-editor/iframe-template.html'; } doOnImportJSModule() { return ''; } doOnModifyCM6Content(title, contentStr) { return undefined; }

后面的4个方法需返回特定值。

子类可覆盖这些方法,以根据特定的需求进行进一步的设置,如调整相应div的高度、设置自己的iframe模板,等等。

打开隐藏的Console面板

Console面板默认情况下是隐藏的。但可通过设置is-show-console属性值来显示该面板。

...

效果:

console.log('Hello World!');

指定输出面板的高度

result-div-height属性值用于设定输出面板的高度。

...

效果:

A centered text.

div.container { display: grid; place-content: center; height: 100vh; } p { font-size: 2em; }

可设置自动高度:

...

效果:

body { display: grid; place-content: center; /* min-height: 100vh; */ } p { margin: 0.5em; font-size: 2em; }

This is a paragraph.

And another paragraph.

当子标签设置了margin属性值时,父容器若需设置高度,应使用可伸缩的min-height,而不是固定的height,否则将失去自动调整高度的功能。此时,最方便的莫过于父容器干脆不设置高度值。

这个功能省心省力。

使用PageConsole

live-editor添加一个use-pageconsole的属性:

<live-editor use-pageconsole> ... </live-editor>

则可在live-editor中直接使用PageConsole

const {clientWidth, clientHeight} = document.querySelector('div'); pc.log('clientWidth: %d', clientWidth); pc.log('clientHeight: %d', clientHeight);

PageConsole将在输出面板的最下面,以折叠的方式输出信息。