Skip to content

Commit

Permalink
feat: playground layout improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
ssmirr committed Oct 21, 2021
1 parent 38ed1d1 commit e3d5a84
Show file tree
Hide file tree
Showing 4 changed files with 275 additions and 84 deletions.
134 changes: 88 additions & 46 deletions lib/notebook/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,62 +261,104 @@ class NotebookRender

const playground =
`
<div class="mb-2">
<div class="d-flex flex-column card">
<div>
<div class="w-100" style="height: 300px;" id="html_playground_content_${elIDWithoutDash}"></div>
<iframe class="w-100" frameBorder="0" id="html_playground_preview_${elIDWithoutDash}"></iframe>
<div class='d-flex flex-row'>
<div class="docable-playground-header-tabs">
<div class="docable-playground-header-tab d-flex">
<div>
HTML
</div>
<svg width="20" height="20" class="my-auto" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<title>HTML5 Logo</title>
<path
d="M108.4 0h23v22.8h21.2V0h23v69h-23V46h-21v23h-23.2M206 23h-20.3V0h63.7v23H229v46h-23M259.5 0h24.1l14.8 24.3L313.2 0h24.1v69h-23V34.8l-16.1 24.8l-16.1-24.8v34.2h-22.6M348.7 0h23v46.2h32.6V69h-55.6" />
<path fill="#e44d26" d="M107.6 471l-33-370.4h362.8l-33 370.2L255.7 512" />
<path fill="#f16529" d="M256 480.5V131H404.3L376 447" />
<path fill="#ebebeb"
d="M142 176.3h114v45.4h-64.2l4.2 46.5h60v45.3H154.4M156.4 336.3H202l3.2 36.3 50.8 13.6v47.4l-93.2-26" />
<path fill="#fff"
d="M369.6 176.3H255.8v45.4h109.6M361.3 268.2H255.8v45.4h56l-5.3 59-50.7 13.6v47.2l93-25.8" />
</svg>
</div>
</div>
<div class="docable-playground-header-badges d-flex flex-row ml-auto">
<div onclick="livePreviewToggle('${elIDWithoutDash}')" class="docable-playground-header-badge docable-playground-header-badge-preview enabled badge badge-pill btn btn-light my-auto"> Live Preview </div>
<div onclick="livePreviewRefresh('${elIDWithoutDash}')" class="docable-playground-header-badge docable-playground-header-badge-refresh badge badge-pill btn btn-light my-auto"> Refresh </div>
</div>
</div>
<div class="mb-2">
<div class="d-flex flex-column" style="border: 1px solid lightgray; border-radius: 0 5px 5px 5px;">
<div class="bg-light" style="height: 300px; min-height: 100px" id="html_playground_content_${elIDWithoutDash}"></div>
<div class="w-100 html_playground_content_resizer" id="html_playground_content_resizer_${elIDWithoutDash}"></div>
<iframe style="min-width: 300px" frameBorder="0" id="html_playground_preview_${elIDWithoutDash}"></iframe>
<div class="w-100 html_playground_preview_resizer" id="html_playground_preview_resizer_${elIDWithoutDash}"></div>
</div>
<script>
const html_playground_content_${elIDWithoutDash} = document.getElementById('html_playground_content_${elIDWithoutDash}');
const html_playground_preview_${elIDWithoutDash} = document.getElementById('html_playground_preview_${elIDWithoutDash}');
require(['vs/editor/editor.main'], function () {
monaco.editor.defineTheme('docable', {
base: 'vs',
inherit: true,
rules: [{ background: 'f6f8fa' }],
colors: {
'editor.background': '#f6f8fa'
makeResizer('html_playground_content_resizer_${elIDWithoutDash}', '${elIDWithoutDash}');
makeResizer('html_playground_preview_resizer_${elIDWithoutDash}', '${elIDWithoutDash}');
const html_playground_content_${elIDWithoutDash} = document.getElementById('html_playground_content_${elIDWithoutDash}');
const html_playground_preview_${elIDWithoutDash} = document.getElementById('html_playground_preview_${elIDWithoutDash}');
window.html_playground_preview_height_is_dirty_${elIDWithoutDash} = false;
//=========
// dynamically update the iframe preview height
html_playground_preview_${elIDWithoutDash}.onload = function () {
if(!window.html_playground_preview_height_is_dirty_${elIDWithoutDash}) {
let html_playground_preview_height = html_playground_preview_${elIDWithoutDash}.contentWindow.document.body.scrollHeight + 100;
html_playground_preview_${elIDWithoutDash}.style.height = (html_playground_preview_height > 600 ? 600 : html_playground_preview_height ) + 'px';
}
});
let el_${elIDWithoutDash} = $('#${el.attr('id')}');
let text_from_${elIDWithoutDash} = htmlDecode(el_${elIDWithoutDash}.find('code').html());
el_${elIDWithoutDash}.empty();
el_${elIDWithoutDash}.remove();
window.html_playground_${elIDWithoutDash} = monaco.editor.create(html_playground_content_${elIDWithoutDash}, {
value: text_from_${elIDWithoutDash},
language: "html",
automaticLayout: true,
minimap: { enabled: false },
theme: 'docable',
scrollBeyondLastLine: false,
overviewRulerLanes: 0,
fixedOverflowWidgets: true,
lineNumbers: true,
quickSuggestions: { other: true, comments: true, strings: true }
});
};
//========
html_playground_preview_${elIDWithoutDash}.srcdoc = text_from_${elIDWithoutDash};
require(['vs/editor/editor.main'], function () {
monaco.editor.defineTheme('docable', {
base: 'vs',
inherit: true,
rules: [{ background: 'f6f8fa' }],
colors: {
'editor.background': '#f6f8fa'
}
});
window.html_playground_${elIDWithoutDash}.onDidChangeModelContent(() => {
html_playground_preview_${elIDWithoutDash}.srcdoc = window.html_playground_${elIDWithoutDash}.getValue();
});
let el_${elIDWithoutDash} = $('#${el.attr('id')}');
let text_from_${elIDWithoutDash} = htmlDecode(el_${elIDWithoutDash}.find('code').html());
window.html_playground_${elIDWithoutDash} = monaco.editor.create(html_playground_content_${elIDWithoutDash}, {
value: text_from_${elIDWithoutDash},
language: "html",
automaticLayout: true,
minimap: { enabled: false },
theme: 'docable',
scrollBeyondLastLine: false,
overviewRulerLanes: 0,
fixedOverflowWidgets: true,
lineNumbers: true,
quickSuggestions: { other: true, comments: true, strings: true }
});
document.addEventListener('RUNNING', function(e) {
setTimeout(() => {
html_playground_preview_${elIDWithoutDash}.srcdoc = window.html_playground_${elIDWithoutDash}.getValue();
}, 3000);
});
html_playground_preview_${elIDWithoutDash}.srcdoc = text_from_${elIDWithoutDash};
window.LivePreviewEvent_${elIDWithoutDash};
window.livePreviewIsEnabled_${elIDWithoutDash} = false;
// update preview on load
livePreviewToggle('${elIDWithoutDash}');
// fix shrink issue for responsive layout
window.addEventListener('resize', ()=>{
window.html_playground_${elIDWithoutDash}.layout({width: 0});
})
});
document.addEventListener('RUNNING', function (e) {
setTimeout(() => {
html_playground_preview_${elIDWithoutDash}.srcdoc = window.html_playground_${elIDWithoutDash}.getValue();
}, 3000);
});
// fix shrink issue for responsive layout
window.addEventListener('resize', () => {
window.html_playground_${elIDWithoutDash}.layout({ width: 0 });
})
});
</script>
</div>`;

Expand Down
74 changes: 74 additions & 0 deletions public/css/notebook.css
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,77 @@ tr.missingVariables > td:nth-child(2) > input:placeholder-shown {
width: 100%;
max-width: 1440px;
}


/* playground style */
.docable-playground-header-tab {
background-color: rgb(247, 247, 247);
border-radius: 5px 5px 0 0;
border: 1px solid lightgray;
border-bottom: 0px;
color: #323232;
display: block;
font-size: 14px;
font-weight: 400;
padding: 8px 15px;
text-align: center;
font-weight: 700;
}

.docable-playground-header-badge {
background-color: rgba(211, 211, 211, 0.5) !important;
}

.docable-playground-header-badge-preview.enabled::before {
/* •◦■⚪⬤ */
content: "●";
color: rgb(117, 196, 0);

margin-top: auto;
margin-bottom: auto;
}

.docable-playground-header-badge-preview::before {
/* •◦■⚪⬤ */
content: "●";
color: red;

margin-top: auto;
margin-bottom: auto;
}

.docable-playground-header-badge-refresh::before {
content: "↻";
margin-top: auto;
margin-bottom: auto;
}

.docable-playground-header-badge-refresh.enabled::before {
content: "↻";
margin-top: auto;
margin-bottom: auto;

display: inline-block;
animation: spin 0.5s 1 linear;
}

@keyframes spin {
from {
transform: rotate(-360deg);
}
}

.html_playground_content_resizer, .html_playground_preview_resizer{
cursor: ns-resize;
box-sizing:border-box;
width: 20px;
height: 3px;
margin: 0px auto;
background-color: darkgray;
}

.html_playground_content_resizer:hover, .html_playground_preview_resizer:hover{
background-color: gold;
height: 4px;
}
/* ================= */
76 changes: 76 additions & 0 deletions public/js/notebook.js
Original file line number Diff line number Diff line change
Expand Up @@ -680,3 +680,79 @@ function htmlDecode(input) {
let doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
}

// playground js ========================================
function makeResizer (id, elIDWithoutDash) {
const resizer = document.getElementById(id);
const previous = resizer.previousElementSibling;
const parent = resizer.parentElement;

let x = 0;
let y = 0;

let topHeight = 0

const mouseDownHandler = function (e) {
x = e.clientX;
y = e.clientY;
topHeight = previous.getBoundingClientRect().height;

document.addEventListener('mousemove', mouseMoveHandler)
document.addEventListener('mouseup', mouseUpHandler);
}

const mouseMoveHandler = function(e) {
const dx = e.clientX - x;
const dy = e.clientY - y;

const newContentHeight = topHeight + dy;
previous.style.height = newContentHeight + 'px';

document.body.style.cursor = 'row-resize';

parent.style.userSelect = 'none';
parent.style.pointerEvents = 'none';

if(previous.id.includes('preview')) window['html_playground_preview_height_is_dirty_' + elIDWithoutDash] = true;
}

const mouseUpHandler = function() {
resizer.style.removeProperty('cursor');
document.body.style.removeProperty('cursor');

parent.style.removeProperty('user-select');
parent.style.removeProperty('pointer-events');

document.removeEventListener('mousemove', mouseMoveHandler);
document.removeEventListener('mouseup', mouseUpHandler);
}

resizer.addEventListener('mousedown', mouseDownHandler);
}

function livePreviewToggle (ID) {
if(window['livePreviewIsEnabled_'+ID]) {
window['LivePreviewEvent_'+ID].dispose();
window['livePreviewIsEnabled_' +ID] = false;
if(event) event.srcElement.classList.remove('enabled');
}
else {
window['LivePreviewEvent_'+ID] = window['html_playground_' + ID].onDidChangeModelContent(() => {
window['html_playground_preview_' + ID].srcdoc = window['html_playground_' + ID].getValue();
});
window['html_playground_preview_' + ID].srcdoc = window['html_playground_'+ID].getValue();
window['livePreviewIsEnabled_' + ID] = true;
if(event) event.srcElement.classList.add('enabled');
}
}

function livePreviewRefresh (ID) {
window['html_playground_preview_'+ID].srcdoc = window['html_playground_' + ID].getValue();

let e = event;
e.srcElement.classList.add('enabled');
setTimeout(()=>{
e.srcElement.classList.remove('enabled');
}, 500)
}
// playground js ========================================
Loading

0 comments on commit e3d5a84

Please sign in to comment.