Skip to content

Commit c4f0340

Browse files
authored
- fix
1 parent ef20d12 commit c4f0340

File tree

1 file changed

+112
-95
lines changed

1 file changed

+112
-95
lines changed

tools/code_editor.html

Lines changed: 112 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -115,107 +115,124 @@
115115
</div>
116116
</div>
117117
<script>
118-
const container = document.getElementById('container');
119-
const toggle = document.getElementById('toggle');
120-
const iframe = document.getElementById('preview');
121-
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
118+
const container = document.getElementById('container');
119+
const toggle = document.getElementById('toggle');
120+
const iframe = document.getElementById('preview');
121+
122+
function compressAndBase64Encode(str) {
123+
return btoa(String.fromCharCode.apply(null, pako.deflate(str))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
124+
}
125+
126+
function base64DecodeAndDecompress(base64EncodedData) {
127+
const adjustedData = base64EncodedData.replace(/-/g, '+').replace(/_/g, '/');
128+
const decodedData = atob(adjustedData);
129+
const charData = decodedData.split('').map(c => c.charCodeAt(0));
130+
const binData = new Uint8Array(charData);
131+
return pako.inflate(binData, { to: 'string' });
132+
}
133+
134+
function updateURL() {
135+
console.log('url updated');
136+
const html = compressAndBase64Encode(document.getElementById('htmlCode').value);
137+
const css = compressAndBase64Encode(document.getElementById('cssCode').value);
138+
const js = compressAndBase64Encode(document.getElementById('jsCode').value);
139+
history.replaceState(null, '', `?html=${html}&css=${css}&js=${js}`);
140+
updatePreview();
141+
}
142+
143+
function updatePreview() {
144+
const html = document.getElementById('htmlCode').value;
145+
const css = document.getElementById('cssCode').value;
146+
const js = document.getElementById('jsCode').value;
122147

123-
function compressAndBase64Encode(str) {
124-
return btoa(String.fromCharCode.apply(null, pako.deflate(str))).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
125-
}
126-
127-
function base64DecodeAndDecompress(base64EncodedData) {
128-
const adjustedData = base64EncodedData.replace(/-/g, '+').replace(/_/g, '/');
129-
const decodedData = atob(adjustedData);
130-
const charData = decodedData.split('').map(c => c.charCodeAt(0));
131-
const binData = new Uint8Array(charData);
132-
return pako.inflate(binData, { to: 'string' });
133-
}
148+
// Create a new iframe to avoid variable redeclaration issues
149+
const oldIframe = document.getElementById('preview');
150+
const newIframe = document.createElement('iframe');
151+
newIframe.id = 'preview';
152+
newIframe.style = 'width: 100%; height: 100%; border: none; flex: 1 1 0%;';
153+
oldIframe.parentNode.replaceChild(newIframe, oldIframe);
134154

135-
function updateURL() {
136-
console.log('url updated');
137-
const html = compressAndBase64Encode(document.getElementById('htmlCode').value);
138-
const css = compressAndBase64Encode(document.getElementById('cssCode').value);
139-
const js = compressAndBase64Encode(document.getElementById('jsCode').value);
140-
history.replaceState(null, '', `?html=${html}&css=${css}&js=${js}`);
141-
decompressAndInject();
142-
}
155+
// Get the new iframe's document
156+
const iframeDoc = newIframe.contentDocument || newIframe.contentWindow.document;
143157

144-
function decompressAndInject() {
145-
let urlParams = new URLSearchParams(window.location.search);
146-
let html = urlParams.get('html') ? sanitizeEncodedValue(urlParams.get('html')) : '';
147-
let css = urlParams.get('css') ? sanitizeEncodedValue(urlParams.get('css')) : '';
148-
let js = urlParams.get('js') ? sanitizeEncodedValue(urlParams.get('js')) : '';
158+
// Write content to the new iframe
159+
iframeDoc.open();
160+
iframeDoc.write(`
161+
<!DOCTYPE html>
162+
<html>
163+
<head>
164+
<style>${css}</style>
165+
</head>
166+
<body>${html}
167+
<script>${js}<\/script>
168+
<script>
169+
(function() {
170+
function handleInputChange(e) {
171+
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.tagName === 'SELECT') {
172+
window.parent.postMessage({
173+
type: 'inputChanged',
174+
html: document.body.innerHTML
175+
}, '*');
176+
}
177+
}
178+
179+
document.addEventListener('input', handleInputChange);
180+
document.addEventListener('change', handleInputChange);
181+
})();
182+
<\/script>
183+
</body>
184+
</html>
185+
`);
186+
iframeDoc.close();
187+
}
188+
189+
function sanitizeEncodedValue(encodedValue) {
190+
return encodedValue.replace(/[\s'"]+$/g, '');
191+
}
192+
193+
function loadFromURL() {
194+
let urlParams = new URLSearchParams(window.location.search);
195+
let html = urlParams.get('html') ? sanitizeEncodedValue(urlParams.get('html')) : '';
196+
let css = urlParams.get('css') ? sanitizeEncodedValue(urlParams.get('css')) : '';
197+
let js = urlParams.get('js') ? sanitizeEncodedValue(urlParams.get('js')) : '';
198+
199+
html = html ? base64DecodeAndDecompress(html) : '';
200+
css = css ? base64DecodeAndDecompress(css) : '';
201+
js = js ? base64DecodeAndDecompress(js) : '';
202+
203+
if (html) document.getElementById('htmlCode').value = html;
204+
if (css) document.getElementById('cssCode').value = css;
205+
if (js) document.getElementById('jsCode').value = js;
149206

150-
html = html ? base64DecodeAndDecompress(html) : '';
151-
css = css ? base64DecodeAndDecompress(css) : '';
152-
js = js ? base64DecodeAndDecompress(js) : '';
153-
154-
if (html) document.getElementById('htmlCode').value = html;
155-
if (css) document.getElementById('cssCode').value = css;
156-
if (js) document.getElementById('jsCode').value = js;
157-
158-
iframeDoc.open();
159-
iframeDoc.write(`
160-
<html>
161-
<head>
162-
<style>${css}</style>
163-
</head>
164-
<body>${html}<script>${js}<\/script>
165-
<script>
166-
document.addEventListener('input', function(e) {
167-
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.tagName === 'SELECT') {
168-
window.parent.postMessage({
169-
type: 'inputChanged',
170-
html: document.body.innerHTML
171-
}, '*');
172-
}
173-
});
174-
document.addEventListener('change', function(e) {
175-
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.tagName === 'SELECT') {
176-
window.parent.postMessage({
177-
type: 'inputChanged',
178-
html: document.body.innerHTML
179-
}, '*');
180-
}
181-
});
182-
<\/script>
183-
</body>
184-
</html>
185-
`);
186-
iframeDoc.close();
207+
updatePreview();
208+
}
209+
210+
document.getElementById('htmlCode').addEventListener('input', updateURL);
211+
document.getElementById('cssCode').addEventListener('input', updateURL);
212+
document.getElementById('jsCode').addEventListener('input', updateURL);
213+
214+
window.addEventListener('message', function(event) {
215+
if (event.data && event.data.type === 'inputChanged') {
216+
document.getElementById('htmlCode').value = event.data.html;
217+
updateURL();
187218
}
188-
189-
function sanitizeEncodedValue(encodedValue) {
190-
return encodedValue.replace(/[\s'"]+$/g, '');
219+
});
220+
221+
loadFromURL();
222+
223+
toggle.addEventListener('click', () => {
224+
const codeEditor = document.getElementById('codeEditor');
225+
const preview = document.getElementById('preview');
226+
if (codeEditor.style.display === 'none' || !codeEditor.style.display) {
227+
codeEditor.style.display = 'flex';
228+
preview.style.flex = '1';
229+
container.classList.remove('collapsed');
230+
} else {
231+
codeEditor.style.display = 'none';
232+
preview.style.flex = '0 0 100%';
233+
container.classList.add('collapsed');
191234
}
192-
193-
document.getElementById('htmlCode').addEventListener('input', updateURL);
194-
document.getElementById('cssCode').addEventListener('input', updateURL);
195-
document.getElementById('jsCode').addEventListener('input', updateURL);
196-
197-
window.addEventListener('message', function(event) {
198-
if (event.data && event.data.type === 'inputChanged') {
199-
document.getElementById('htmlCode').value = event.data.html;
200-
updateURL();
201-
}
202-
});
203-
204-
decompressAndInject();
205-
206-
toggle.addEventListener('click', () => {
207-
const codeEditor = document.getElementById('codeEditor');
208-
const preview = document.getElementById('preview');
209-
if (codeEditor.style.display === 'none' || !codeEditor.style.display) {
210-
codeEditor.style.display = 'flex';
211-
preview.style.flex = '1';
212-
container.classList.remove('collapsed');
213-
} else {
214-
codeEditor.style.display = 'none';
215-
preview.style.flex = '0 0 100%';
216-
container.classList.add('collapsed');
217-
}
218-
});
235+
});
219236
</script>
220237
<script src="../logo.js"></script>
221238
</body>

0 commit comments

Comments
 (0)