Skip to content

Commit 0707dda

Browse files
committed
feat: add a sample using a webcomponent
1 parent 04a6536 commit 0707dda

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed

tests/webcomponent.html

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
<!doctype html>
2+
<html>
3+
4+
<head>
5+
<meta charset="utf-8" />
6+
<title>Blockly Playground Webcomponent</title>
7+
8+
<script type="module">
9+
import { COMPRESSED, loadScript } from './scripts/load.mjs';
10+
11+
import * as Blockly from '../build/blockly.loader.mjs';
12+
import '../build/blocks.loader.mjs';
13+
import { dartGenerator } from '../build/dart.loader.mjs';
14+
import { luaGenerator } from '../build/lua.loader.mjs';
15+
import { javascriptGenerator } from '../build/javascript.loader.mjs';
16+
import { phpGenerator } from '../build/php.loader.mjs';
17+
import { pythonGenerator } from '../build/python.loader.mjs';
18+
19+
await loadScript('../build/msg/en.js');
20+
await loadScript('playgrounds/screenshot.js');
21+
await loadScript('../node_modules/@blockly/dev-tools/dist/index.js');
22+
23+
function toParString(strings, values) {
24+
if (strings.length === 1)
25+
return strings.raw[0];
26+
else {
27+
let r = ''
28+
for (let i = 0; i < strings.length; i++) {
29+
r += strings[i] + (values[i] ?? '');
30+
}
31+
return r;
32+
}
33+
}
34+
35+
const html = function (strings, ...values) {
36+
const template = document.createElement('template');
37+
template.innerHTML = toParString(strings, values);
38+
return template;
39+
};
40+
41+
const css = function (strings, ...values) {
42+
const cssStyleSheet = new CSSStyleSheet();
43+
cssStyleSheet.replaceSync(toParString(strings, values));
44+
return cssStyleSheet;
45+
};
46+
47+
let toolbox = {
48+
"kind": "flyoutToolbox",
49+
"contents": [
50+
{
51+
"kind": "block",
52+
"type": "controls_if"
53+
},
54+
{
55+
"kind": "block",
56+
"type": "controls_whileUntil"
57+
},
58+
{
59+
type: 'text',
60+
kind: 'block',
61+
fields: {
62+
TEXT: '',
63+
},
64+
},
65+
]
66+
};
67+
68+
class BlocklyComponent extends HTMLElement {
69+
70+
static template = html`
71+
<div id="blocklyDiv" style="position: absolute; width: 100%; height: 100%;"></div>
72+
`;
73+
74+
static style = css`
75+
:host {
76+
box-sizing: border-box;
77+
position: absolute;
78+
height: 100%;
79+
width: 100%;
80+
}`;
81+
82+
static blocklyStyle1;
83+
static blocklyStyle2;
84+
85+
blocklyDiv;
86+
workspace;
87+
resizeObserver;
88+
89+
constructor() {
90+
super();
91+
this.attachShadow({ mode: 'open' });
92+
this.shadowRoot.adoptedStyleSheets = [BlocklyComponent.style];
93+
this.shadowRoot.appendChild(BlocklyComponent.template.content.cloneNode(true));
94+
95+
this.blocklyDiv = this.shadowRoot.getElementById('blocklyDiv');
96+
this.createBlockly();
97+
}
98+
99+
createBlockly() {
100+
this.workspace = Blockly.inject(this.blocklyDiv, {
101+
toolbox: toolbox,
102+
renderer: 'zelos',
103+
trashcan: true,
104+
zoom: {
105+
controls: true,
106+
wheel: false,
107+
startScale: 0.7,
108+
maxScale: 3,
109+
minScale: 0.3,
110+
scaleSpeed: 1.2,
111+
pinch: false
112+
},
113+
move: {
114+
scrollbars: {
115+
horizontal: true,
116+
vertical: true
117+
},
118+
drag: true,
119+
wheel: true
120+
}
121+
});
122+
123+
if (!BlocklyComponent.blocklyStyle1) {
124+
BlocklyComponent.blocklyStyle1 = document.getElementById('blockly-renderer-style-zelos-classic');
125+
this.shadowRoot.appendChild(BlocklyComponent.blocklyStyle1);
126+
BlocklyComponent.blocklyStyle2 = document.getElementById('blockly-common-style');
127+
this.shadowRoot.appendChild(BlocklyComponent.blocklyStyle2);
128+
} else {
129+
this.shadowRoot.appendChild(BlocklyComponent.blocklyStyle1.cloneNode(true));
130+
this.shadowRoot.appendChild(BlocklyComponent.blocklyStyle2.cloneNode(true));
131+
}
132+
}
133+
134+
connectedCallback() {
135+
Blockly.svgResize(this.workspace);
136+
137+
if (!resizeObserver) {
138+
this.resizeObserver = new ResizeObserver((entries) => {
139+
Blockly.svgResize(this.workspace);
140+
});
141+
this.resizeObserver.observe(this);
142+
}
143+
}
144+
145+
save() {
146+
const state = Blockly.serialization.workspaces.save(this.workspace);
147+
return state;
148+
}
149+
150+
load(data) {
151+
Blockly.serialization.workspaces.load(data, this.workspace);
152+
}
153+
}
154+
customElements.define('blockly-component', BlocklyComponent);
155+
</script>
156+
157+
<style>
158+
html,
159+
body {
160+
height: 100%;
161+
}
162+
163+
body {
164+
background-color: #fff;
165+
font-family: sans-serif;
166+
overflow: hidden;
167+
}
168+
169+
h1 {
170+
font-weight: normal;
171+
font-size: 140%;
172+
}
173+
174+
#blocklyDiv {
175+
float: right;
176+
height: 95%;
177+
width: 70%;
178+
}
179+
180+
#importExport {
181+
font-family: monospace;
182+
}
183+
184+
.ioLabel>.blocklyFlyoutLabelText {
185+
font-style: italic;
186+
}
187+
188+
#blocklyDiv.renderingDebug .blockRenderDebug {
189+
display: block;
190+
}
191+
192+
.playgroundToggleOptions {
193+
list-style: none;
194+
padding: 0;
195+
}
196+
197+
.playgroundToggleOptions li {
198+
margin-top: 1em;
199+
}
200+
201+
.zelos-renderer .blocklyFlyoutButton .blocklyText {
202+
font-size: 1.5rem;
203+
}
204+
</style>
205+
</head>
206+
207+
<body>
208+
<blockly-component style="position:absolute; left: 50px; top: 50px; width: 500px; height: 600px;"></blockly-component>
209+
<blockly-component
210+
style="position:absolute; left: 600px; top: 50px; width: 500px; height: 600px;"></blockly-component>
211+
</body>
212+
213+
</html>

0 commit comments

Comments
 (0)