aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Layout.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Layout.mjs')
-rw-r--r--src/Layout.mjs88
1 files changed, 44 insertions, 44 deletions
diff --git a/src/Layout.mjs b/src/Layout.mjs
index 9cf2ab9..3a835c9 100644
--- a/src/Layout.mjs
+++ b/src/Layout.mjs
@@ -1,9 +1,9 @@
1import PlainDraggable from "plain-draggable"; 1import PlainDraggable from 'plain-draggable';
2import { onRemove, animateRectTransition } from "./utils"; 2import { onRemove, animateRectTransition } from './utils';
3 3
4export class Layout { 4export class Layout {
5 constructor(options = {}) { 5 constructor(options = {}) {
6 if (!options.name) throw Error("Layout name is not given"); 6 if (!options.name) throw Error('Layout name is not given');
7 this.name = options.name; 7 this.name = options.name;
8 this.enterHandler = options.enterHandler; 8 this.enterHandler = options.enterHandler;
9 this.leaveHandler = options.leaveHandler; 9 this.leaveHandler = options.leaveHandler;
@@ -12,63 +12,63 @@ export class Layout {
12} 12}
13 13
14export class SideBySide extends Layout { 14export class SideBySide extends Layout {
15 name = "side-by-side"; 15 name = 'side-by-side';
16 16
17 enterHandler = ({ container, htmlHolder, showcase }) => { 17 enterHandler = ({ container, htmlHolder, showcase }) => {
18 const bar = document.createElement("div"); 18 const bar = document.createElement('div');
19 bar.className = "bar"; 19 bar.className = 'bar';
20 bar.innerHTML = '<div class="bar-handle"></div>'; 20 bar.innerHTML = '<div class="bar-handle"></div>';
21 const handle = bar.querySelector(".bar-handle"); 21 const handle = bar.querySelector('.bar-handle');
22 container.appendChild(bar); 22 container.appendChild(bar);
23 23
24 // Resize views by value 24 // Resize views by value
25 const resizeByLeft = left => { 25 const resizeByLeft = left => {
26 htmlHolder.style.width = left + "px"; 26 htmlHolder.style.width = left + 'px';
27 showcase.style.width = 27 showcase.style.width =
28 parseFloat(getComputedStyle(container).width) - left + "px"; 28 parseFloat(getComputedStyle(container).width) - left + 'px';
29 }; 29 };
30 30
31 const draggable = new PlainDraggable(bar, { 31 const draggable = new PlainDraggable(bar, {
32 handle: handle, 32 handle: handle,
33 containment: { left: "25%", top: 0, right: "75%", height: 0 }, 33 containment: { left: '25%', top: 0, right: '75%', height: 0 },
34 }); 34 });
35 draggable.draggableCursor = "grab"; 35 draggable.draggableCursor = 'grab';
36 36
37 draggable.onDrag = pos => { 37 draggable.onDrag = pos => {
38 handle.style.transform = "unset"; 38 handle.style.transform = 'unset';
39 resizeByLeft(pos.left); 39 resizeByLeft(pos.left);
40 }; 40 };
41 draggable.onDragEnd = _ => { 41 draggable.onDragEnd = _ => {
42 handle.removeAttribute("style"); 42 handle.removeAttribute('style');
43 }; 43 };
44 44
45 onRemove(bar, () => draggable.remove()); 45 onRemove(bar, () => draggable.remove());
46 }; 46 };
47 47
48 leaveHandler = ({ container }) => { 48 leaveHandler = ({ container }) => {
49 container.querySelector(".bar")?.remove(); 49 container.querySelector('.bar')?.remove();
50 }; 50 };
51} 51}
52 52
53export class Overlay extends Layout { 53export class Overlay extends Layout {
54 name = "overlay"; 54 name = 'overlay';
55 55
56 saveLeftTopAsData = element => { 56 saveLeftTopAsData = element => {
57 const { left, top } = element.getBoundingClientRect(); 57 const { left, top } = element.getBoundingClientRect();
58 element.setAttribute("data-left", left); 58 element.setAttribute('data-left', left);
59 element.setAttribute("data-top", top); 59 element.setAttribute('data-top', top);
60 }; 60 };
61 61
62 addDraggable = element => { 62 addDraggable = element => {
63 // Make sure current element always on top 63 // Make sure current element always on top
64 const siblings = Array.from( 64 const siblings = Array.from(
65 element.parentElement?.querySelectorAll(":scope > *") ?? [], 65 element.parentElement?.querySelectorAll(':scope > *') ?? [],
66 ); 66 );
67 let popTimer = null; 67 let popTimer = null;
68 element.onmouseover = () => { 68 element.onmouseover = () => {
69 popTimer = setTimeout(() => { 69 popTimer = setTimeout(() => {
70 siblings.forEach(e => e.style.removeProperty("z-index")); 70 siblings.forEach(e => e.style.removeProperty('z-index'));
71 element.style.zIndex = "9001"; 71 element.style.zIndex = '9001';
72 }, 200); 72 }, 200);
73 }; 73 };
74 element.onmouseout = () => { 74 element.onmouseout = () => {
@@ -76,9 +76,9 @@ export class Overlay extends Layout {
76 }; 76 };
77 77
78 // Add draggable part 78 // Add draggable part
79 const draggablePart = document.createElement("div"); 79 const draggablePart = document.createElement('div');
80 element.appendChild(draggablePart); 80 element.appendChild(draggablePart);
81 draggablePart.className = "draggable-part"; 81 draggablePart.className = 'draggable-part';
82 draggablePart.innerHTML = '<div class="handle">\u2630</div>'; 82 draggablePart.innerHTML = '<div class="handle">\u2630</div>';
83 83
84 // Add draggable instance 84 // Add draggable instance
@@ -91,16 +91,16 @@ export class Overlay extends Layout {
91 }); 91 });
92 92
93 // FIXME use pure CSS to hide utils 93 // FIXME use pure CSS to hide utils
94 const utils = element.querySelector(".utils"); 94 const utils = element.querySelector('.utils');
95 draggable.onDragStart = () => { 95 draggable.onDragStart = () => {
96 utils.style.display = "none"; 96 utils.style.display = 'none';
97 element.classList.add("drag"); 97 element.classList.add('drag');
98 }; 98 };
99 99
100 draggable.onDragEnd = () => { 100 draggable.onDragEnd = () => {
101 utils.style = ""; 101 utils.style = '';
102 element.classList.remove("drag"); 102 element.classList.remove('drag');
103 element.style.zIndex = "9000"; 103 element.style.zIndex = '9000';
104 }; 104 };
105 105
106 // Reposition draggable instance when resized 106 // Reposition draggable instance when resized
@@ -125,12 +125,12 @@ export class Overlay extends Layout {
125 // Create draggable blocks and set each position by previous one 125 // Create draggable blocks and set each position by previous one
126 let [left, top] = [20, 20]; 126 let [left, top] = [20, 20];
127 blocks.forEach(block => { 127 blocks.forEach(block => {
128 const originLeft = Number(block.getAttribute("data-left")); 128 const originLeft = Number(block.getAttribute('data-left'));
129 const originTop = Number(block.getAttribute("data-top")); 129 const originTop = Number(block.getAttribute('data-top'));
130 130
131 // Create draggable block 131 // Create draggable block
132 const wrapper = document.createElement("div"); 132 const wrapper = document.createElement('div');
133 wrapper.classList.add("draggable-block"); 133 wrapper.classList.add('draggable-block');
134 wrapper.innerHTML = ` 134 wrapper.innerHTML = `
135 <div class="utils"> 135 <div class="utils">
136 <div id="close">\u274C</div> 136 <div id="close">\u274C</div>
@@ -138,18 +138,18 @@ export class Overlay extends Layout {
138 <div id="minus-font-size">\u2796</div> 138 <div id="minus-font-size">\u2796</div>
139 </div> 139 </div>
140 `; 140 `;
141 wrapper.title = "Middle-click to hide block"; 141 wrapper.title = 'Middle-click to hide block';
142 wrapper.onmouseup = e => { 142 wrapper.onmouseup = e => {
143 // Hide block with middle click 143 // Hide block with middle click
144 if (e.button === 1) { 144 if (e.button === 1) {
145 wrapper.classList.add("hide"); 145 wrapper.classList.add('hide');
146 } 146 }
147 }; 147 };
148 148
149 // Set DOMRect for wrapper 149 // Set DOMRect for wrapper
150 wrapper.appendChild(block); 150 wrapper.appendChild(block);
151 wrapper.style.left = left + "px"; 151 wrapper.style.left = left + 'px';
152 wrapper.style.top = top + "px"; 152 wrapper.style.top = top + 'px';
153 htmlHolder.appendChild(wrapper); 153 htmlHolder.appendChild(wrapper);
154 const { width } = wrapper.getBoundingClientRect(); 154 const { width } = wrapper.getBoundingClientRect();
155 left += width + 30; 155 left += width + 30;
@@ -168,7 +168,7 @@ export class Overlay extends Layout {
168 // Trivial case: 168 // Trivial case:
169 // This hack make sure utils remains at the same place even when wrapper resized 169 // This hack make sure utils remains at the same place even when wrapper resized
170 // Prevent DOMRect changes when user clicking plus/minus button many times 170 // Prevent DOMRect changes when user clicking plus/minus button many times
171 const utils = wrapper.querySelector(".utils"); 171 const utils = wrapper.querySelector('.utils');
172 utils.onmouseover = () => { 172 utils.onmouseover = () => {
173 const { left, top } = utils.getBoundingClientRect(); 173 const { left, top } = utils.getBoundingClientRect();
174 utils.style.cssText = `visibility: visible; z-index: 9000; position: fixed; transition: unset; left: ${left}px; top: ${top}px;`; 174 utils.style.cssText = `visibility: visible; z-index: 9000; position: fixed; transition: unset; left: ${left}px; top: ${top}px;`;
@@ -176,20 +176,20 @@ export class Overlay extends Layout {
176 }; 176 };
177 utils.onmouseout = () => { 177 utils.onmouseout = () => {
178 wrapper.appendChild(utils); 178 wrapper.appendChild(utils);
179 utils.removeAttribute("style"); 179 utils.removeAttribute('style');
180 }; 180 };
181 181
182 // Close button 182 // Close button
183 wrapper.querySelector("#close").onclick = () => { 183 wrapper.querySelector('#close').onclick = () => {
184 wrapper.classList.add("hide"); 184 wrapper.classList.add('hide');
185 utils.removeAttribute("style"); 185 utils.removeAttribute('style');
186 }; 186 };
187 // Plus/Minus font-size of content 187 // Plus/Minus font-size of content
188 wrapper.querySelector("#plus-font-size").onclick = () => { 188 wrapper.querySelector('#plus-font-size').onclick = () => {
189 const fontSize = parseFloat(getComputedStyle(block).fontSize) / 16; 189 const fontSize = parseFloat(getComputedStyle(block).fontSize) / 16;
190 block.style.fontSize = `${fontSize + 0.2}rem`; 190 block.style.fontSize = `${fontSize + 0.2}rem`;
191 }; 191 };
192 wrapper.querySelector("#minus-font-size").onclick = () => { 192 wrapper.querySelector('#minus-font-size').onclick = () => {
193 const fontSize = parseFloat(getComputedStyle(block).fontSize) / 16; 193 const fontSize = parseFloat(getComputedStyle(block).fontSize) / 16;
194 block.style.fontSize = `${fontSize - 0.2}rem`; 194 block.style.fontSize = `${fontSize - 0.2}rem`;
195 }; 195 };
@@ -198,7 +198,7 @@ export class Overlay extends Layout {
198 198
199 leaveHandler = ({ htmlHolder, blocks }) => { 199 leaveHandler = ({ htmlHolder, blocks }) => {
200 const resumeFromDraggable = block => { 200 const resumeFromDraggable = block => {
201 const draggableContainer = block.closest(".draggable-block"); 201 const draggableContainer = block.closest('.draggable-block');
202 if (!draggableContainer) return; 202 if (!draggableContainer) return;
203 htmlHolder.appendChild(block); 203 htmlHolder.appendChild(block);
204 draggableContainer.remove(); 204 draggableContainer.remove();