Source html
<dialog open id="dragdialog" tabindex="-1" role="dialog" class="ui-dialog ui-corner-all ui-widget ui-widget-content ui-front ui-draggable ui-resizable txp-preview-container" aria-describedby="ui-id-1" aria-labelledby="ui-id-2">
<div class="header ui-dialog-titlebar ui-corner-all ui-widget-header ui-helper-clearfix ui-draggable-handle">
<span id="ui-id-2" class="ui-dialog-title">Body Preview</span>
<div class="ui-dialog-controls">
<button id="dragdialog-expand">Expand</button>
<button id="details-close" type="button" class="ui-button ui-corner-all ui-widget ui-button-icon-only ui-dialog-titlebar-close" title="Close"><span class="ui-button-icon ui-icon ui-icon-closethick"></span><span class="ui-button-icon-space"> </span>Close</button>
</div>
</div>
<div class="txp-dialog ui-dialog-content ui-widget-content" id="ui-id-1">
<div id="view_modes">
<div class="txp-textarea-options txp-live-preview">
<label><input class="checkbox" id="parse-preview" name="_txp_parse" type="checkbox" form="article_form" value="1"> Tags</label>
<label><input class="checkbox active" id="clean-preview" type="checkbox" checked="checked" value="1"> Sanitize</label>
<label><input class="checkbox" id="live-preview" type="checkbox" value="1"> Live preview</label>
</div>
<details id="page-preview">
<summary id="page-preview-open">Page Preview</summary>
</details>
<details id="text-preview" open class="active">
<summary>Text Preview</summary>
<div>
<h2>h2 Title</h2>
<p><a href="">Modernipsum</a> dolor sit amet postminimalism, art deco nouveau realisme art nouveau mail art fluxus, <em>social realism</em> stuckism post-painterly abstraction.</p>
<p>Formalism <small>post modern</small> baroque relational art ottonian russian <strong>symbolism</strong> monumentalism realism neue slowenische kunst, synchromism carolingian bauhaus superflat art deco carolingian<sup class="footnote" id="fnrev1193694580674a7edb2fc58-1"><a href="#fn1193694580674a7edb2fc58-1">1</a></sup>.</p>
<p class="footnote" id="fn1193694580674a7edb2fc58-1"><sup>1</sup> <a href="">Fluxus painting tachism caravaggisti</a>.</p>
</div>
</details>
<details id="pane-html">
<summary>HTML Preview</summary>
<pre>
<code>
<h2>h2 Title</h2>
<p><a href="">Modernipsum</a> dolor sit amet postminimalism, art deco nouveau realisme art nouveau mail art fluxus, <em>social realism</em> stuckism post-painterly abstraction.</p>
<p>Formalism <small>post modern</small> baroque relational art ottonian russian <strong>symbolism</strong> monumentalism realism neue slowenische kunst, synchromism carolingian bauhaus superflat art deco carolingian<sup class="footnote" id="fnrev1193694580674a7edb2fc58-1"><a href="#fn1193694580674a7edb2fc58-1">1</a></sup>.</p>
<p class="footnote" id="fn1193694580674a7edb2fc58-1"><sup>1</sup> <a href="">Fluxus painting tachism caravaggisti</a>.</p></code>
</pre>
</details>
</ul>
</div>
<template id="pane-template"></template>
</div>
</dialog>
<!-- <dialog id="dragdialog2" tabindex="-1" role="dialog" class="ui-dialog ui-corner-all ui-widget ui-widget-content ui-front ui-draggable ui-resizable txp-preview-container" aria-describedby="ui-id-1" aria-labelledby="ui-id-2" style="left:0">
<div class="header ui-dialog-titlebar ui-corner-all ui-widget-header ui-helper-clearfix ui-draggable-handle">
<span id="ui-id-2" class="ui-dialog-title">Body</span>
<button id="jqui-close" type="button" class="ui-button ui-corner-all ui-widget ui-button-icon-only ui-dialog-titlebar-close" title="Close"><span class="ui-button-icon ui-icon ui-icon-closethick"></span><span class="ui-button-icon-space"> </span>Close</button>
</div>
<div class="txp-dialog ui-dialog-content ui-widget-content" id="ui-id-1">
<div id="view_modes">
<div class="txp-textarea-options txp-live-preview"><label>
<input class="checkbox" id="parse-preview" name="_txp_parse" type="checkbox" form="article_form" value="1"> Tags</label><label>
<input class="checkbox active" id="clean-preview" type="checkbox" checked="checked" value="1"> Sanitize</label><label>
<input class="checkbox" id="live-preview" type="checkbox" value="1"> Live preview</label>
</div>
<ul>
<li id="tab-preview" class="active"><button data-view-mode="preview" aria-pressed="false" class="txp-reduced-ui-button">Text</button></li>
<li id="tab-html"><button data-view-mode="html" aria-pressed="false" class="txp-reduced-ui-button"><bdi dir="ltr">HTML</bdi></button></li>
</ul>
</div>
<div id="pane-preview" class="preview">
<h2>h2 Title</h2>
<p><a href="">Modernipsum</a> dolor sit amet postminimalism, art deco nouveau realisme art nouveau mail art fluxus, <em>social realism</em> stuckism post-painterly abstraction.</p>
<p>Formalism <small>post modern</small> baroque relational art ottonian russian <strong>symbolism</strong> monumentalism realism neue slowenische kunst, synchromism carolingian bauhaus superflat art deco carolingian<sup class="footnote" id="fnrev1193694580674a7edb2fc58-1"><a href="#fn1193694580674a7edb2fc58-1">1</a></sup>.</p>
<p class="footnote" id="fn1193694580674a7edb2fc58-1"><sup>1</sup> <a href="">Fluxus painting tachism caravaggisti</a>.</p>
</div>
<template id="pane-template"></template>
</div>
<div class="ui-resizable-handle ui-resizable-n" style="z-index: 90;"></div>
<div class="ui-resizable-handle ui-resizable-e" style="z-index: 90;"></div>
<div class="ui-resizable-handle ui-resizable-s" style="z-index: 90;"></div>
<div class="ui-resizable-handle ui-resizable-w" style="z-index: 90;"></div>
<div class="ui-resizable-handle ui-resizable-se ui-icon ui-icon-gripsmall-diagonal-se" style="z-index: 90;"></div>
<div class="ui-resizable-handle ui-resizable-sw" style="z-index: 90;"></div>
<div class="ui-resizable-handle ui-resizable-ne" style="z-index: 90;"></div>
<div class="ui-resizable-handle ui-resizable-nw" style="z-index: 90;"></div>
</dialog> -->
<script>
// https://iut-fbleau.fr/projet/etc/sandbox/vanillajs-ui
(() => {
const preventDefault = (e) => {
e.preventDefault()
};
const handleDragStart = (e) => { //console.log(e);
let timeout;
const target = e.currentTarget;
const dragEle = target.parentElement;
const posX = ('clientX' in e ? e.clientX : e.changedTouches[0].clientX),
posY = ('clientY' in e ? e.clientY : e.changedTouches[0].clientY);
const posLeft = dragEle.offsetLeft,
posTop = dragEle.offsetTop;
setTimeout(() => {
dragEle.style.left = posLeft + 'px';
dragEle.style.top = posTop + 'px';
dragEle.style.margin = 0;
}, 0);
const handleDragEnd = (e) => {
if (timeout) {
window.cancelAnimationFrame(timeout);
}
timeout = window.requestAnimationFrame((t) => { //timeout = undefined;
let pos1 = ('clientX' in e ? e.clientX : e.changedTouches[0].clientX);
let pos2 = ('clientY' in e ? e.clientY : e.changedTouches[0].clientY);
dragEle.style.left = `max(min(${posLeft - posX + pos1}px, 100% - ${dragEle.offsetWidth}px), 0px)`;
dragEle.style.top = `max(min(${posTop - posY + pos2}px, 100% - ${dragEle.offsetHeight}px), 0px)`;
});
if (e.type != "touchmove") { //console.log(e);
if (e.type == "dragend" || e.type == "drop") {
document.removeEventListener("dragover", preventDefault);
target.removeEventListener('dragend', handleDragEnd);
document.removeEventListener("drop", handleDragEnd);
}
target.removeEventListener('touchend', handleDragEnd);
target.removeEventListener('touchmove', handleDragEnd);
}
};
if (e.type == "dragstart") {
document.addEventListener('drop', handleDragEnd);
document.addEventListener("dragover", preventDefault);
const nodeRect = dragEle.getBoundingClientRect();
e.dataTransfer.setDragImage(dragEle, posX - nodeRect.left, posY - nodeRect.top);
// e.dataTransfer.effectAllowed = "move";
const boxShadow = dragEle.style.boxShadow;
dragEle.style.boxShadow = 'none';
setTimeout(() => {
dragEle.style.left = '-200vw';
dragEle.style.boxShadow = boxShadow;
}, 0);
target.addEventListener('dragend', handleDragEnd);
} else {
target.setAttribute('draggable', false);
target.removeEventListener('dragstart', handleDragStart);
target.addEventListener("touchmove", handleDragEnd);
target.addEventListener("touchend", handleDragEnd);
}
};
// Make the DIV element draggable:
document.querySelectorAll("dialog").forEach((t) => {
const handler = t.querySelector("div.header");
handler.addEventListener('pointerdown', e => { //console.log(e)
handler.setAttribute('draggable', true);
handler.addEventListener('dragstart', handleDragStart);
handler.addEventListener("touchstart", handleDragStart);
});
/*
handler.addEventListener('pointerup', e => {console.log(e)
handler.setAttribute('draggable', false);
handler.removeEventListener('dragstart', handleDragStart);
handler.removeEventListener("touchstart", handleDragStart);
});
*/
});
})();
</script>
<script>
const dragdialog = document.getElementById("dragdialog");
document.getElementById("details-close").addEventListener("click", (e) => {
dragdialog.removeAttribute("open");
});
document.getElementById("page-preview-open").addEventListener("click", (e) => {
document.getElementById("page-preview").innerHTML += '<iframe src="/"></iframe>';
document.getElementById("page-preview").open = true;;
});
let dragdialogExpanded = 0;
let origH = dragdialog.offsetHeight + "px";
let origW = dragdialog.offsetWidth + "px";
document.getElementById("dragdialog-expand").addEventListener("click", (e) => {
if (dragdialogExpanded == 0) {
let windowH = document.documentElement.clientHeight;
let windowW = document.documentElement.clientWidth;
dragdialog.style.height = windowH + 'px';
dragdialog.style.width = windowW + 'px';
document.getElementById("dragdialog-expand").innerHTML = "Reduce";
dragdialogExpanded = 1;
} else {
dragdialog.style.height = origH;
dragdialog.style.width = origW;
dragdialogExpanded = 0;
document.getElementById("dragdialog-expand").innerHTML = "Expand";
}
});
// Create a class for the element
class MovableDialog extends HTMLDialogElement {
constructor() {
super();
this.style.margin = 0;
}
connectedCallback() {
const handlers = Array.from(this.querySelectorAll("div.header"));
handlers.forEach((handler) => {
handler.addEventListener('pointerdown', e => {
if (e.button) return true;
e.preventDefault();
const viewH = document.documentElement.clientHeight - handler.offsetHeight;
const viewW = document.documentElement.clientWidth - this.offsetWidth;
const handleDrag = (e) => {
e.preventDefault();
e.stopPropagation();
this.style.left = `max(min(${this.offsetLeft + e.movementX}px, ${viewW}px), 0px)`;
this.style.top = `max(min(${this.offsetTop + e.movementY}px, ${viewH}px), 0px)`;
};
const handleDragEnd = (e) => {
e.preventDefault();
this.classList.remove('fadeout');
this.releasePointerCapture(e.pointerId);
this.removeEventListener('pointermove', handleDrag, true);
this.removeEventListener('pointerup', handleDragEnd);
};
this.classList.add('fadeout');
this.setPointerCapture(e.pointerId);
this.addEventListener('pointermove', handleDrag, true);
this.addEventListener('pointerup', handleDragEnd);
});
});
}
}
customElements.define("movable-dialog", MovableDialog, {
extends: "dialog"
});
</script>