-
-
WinBox is a modern HTML5 window manager for the web. Lightweight, outstanding performance, no dependencies, fully customizable, free and open source!
-
-
Show Example
-
-
-
-
- Please feel free to support me by making a personal donation which helps me a lot to keep this project alive and also to providing all the contribution to keep WinBox.js on a professional top-end level.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Thanks a lot,
- Thomas (ts-thomas)
+
+
+
+
+
+
+ WinBox is a modern HTML5 window manager for the web. Lightweight,
+ outstanding performance, no dependencies, fully customizable, free and
+ open source!
+
+
+
+ Show Example
+
+
+
+
+
+ Please feel free to support me by making a personal donation which
+ helps me a lot to keep this project alive and also to providing all
+ the contribution to keep WinBox.js on a professional top-end level.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Thanks a lot, Thomas (ts-thomas)
-
-
+
+
Load Library (Bundle)
-
-
<head>
+
+ <head>
<script src="dist/winbox.bundle.min.js"></script>
</head>
-
+
Load Library (Non-Bundle)
-
+
<head>
<link rel="stylesheet" href="dist/css/winbox.min.css">
<script src="dist/js/winbox.min.js"></script>
</head>
-
-
+
+
Class Constructor
-
+
WinBox(title, options<key: value>)
-
+
-
-
- You can open the browser dev tools and copy and paste the js-code blocks into the console and play with them.
+
+
+
+ You can open the browser dev tools and copy and paste the js-code
+ blocks into the console and play with them.
+
-
-
+
+
Basic Window
-
+
new WinBox("Basic Window");
Run Code
-
+
-
-
+
+
Custom Root
-
+
new WinBox("Custom Root", {
root: document.querySelector("main")
});
Run Code
-
+
-
-
+
+
Custom Border
-
+
new WinBox("Custom Border", {
border: "0.3em"
});
Run Code
-
+
-
-
+
+
Custom Color
-
+
new WinBox({
title: "Custom Color",
background: "#ff005d",
@@ -244,12 +341,12 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
});
Run Code
-
+
-
-
+
+
Custom Icon (Titlebar)
-
+
new WinBox({
title: "Custom Icon",
icon: "demo/wikipedia.svg",
@@ -257,12 +354,12 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
});
Run Code
-
+
-
-
+
+
Limit Viewport
-
+
new WinBox("Limit Viewport", {
top: 50,
right: 50,
@@ -270,13 +367,15 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
left: 50
});
- Run Code
-
+
+ Run Code
+
+
-
-
+
+
Splitscreen
-
+
new WinBox("Splitscreen (Left)", {
right: "50%",
max: true
@@ -287,13 +386,15 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
max: true
});
- Run Code
-
+
+ Run Code
+
+
-
-
+
+
Custom Position / Size
-
+
new WinBox({
title: "Custom Position / Size",
x: "center",
@@ -302,36 +403,40 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
height: "50%"
});
- Run Code
-
+
+ Run Code
+
+
-
-
+
+
Modal Window
-
+
new WinBox("Modal Window", {
modal: true
});
Run Code
-
+
-
-
+
+
Set innerHTML
-
+
new WinBox({
title: "Set innerHTML",
html: "<h1>Lorem Ipsum</h1>"
});
- Run Code
-
+
+ Run Code
+
+
-
-
+
+
Mount DOM (Cloned)
-
+
<div id="backstore" style="display: none">
<div id="content">
@@ -347,35 +452,39 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
.cloneNode(true)
});
- Run Code
-
+
+ Run Code
+
+
-
-
+
+
Mount DOM (Singleton) + Auto-Unmount
-
+
new WinBox("Mount DOM", {
mount: document.getElementById("content")
});
- Run Code
-
+
+ Run Code
+
+
-
-
+
+
Open URI / URL
-
+
new WinBox("WinBox.js", {
url: "https://nextapps-de.github.io/winbox/"
});
Run Code
-
+
-
-
+
+
All Options
-
+
new WinBox({
// configuration:
index: 1,
@@ -461,13 +570,15 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
}
});
- Run Code
-
+
+ Run Code
+
+
-
-
+
+
Control Programmatically
-
+
<div id="controls">
<button onclick="buttons.minimize()">Minimize (Toggle)</button>
<button onclick="buttons.maximize()">Maximize (Toggle)</button>
@@ -478,8 +589,8 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
<button onclick="buttons.color()">Set Color</button>
<button onclick="buttons.close()">Close</button>
</div>
-
- var winbox = new WinBox("Controls", {
+
+ var winbox = new WinBox("Controls", {
mount: document.getElementById("controls"),
border: 4,
onclose: function(force){
@@ -534,19 +645,21 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
}
};
- Run Code
-
+
+ Run Code
+
+
-
-
+
+
Window Boilerplate
-
-
+
+
-
-
+
+
Custom Styles (Global)
-
+
.winbox {
background: linear-gradient(90deg, #ff00f0, #0050ff);
border-radius: 12px 12px 0 0;
@@ -572,7 +685,7 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
Customize Control Icons
-
+
.wb-control * {
opacity: 0.65;
}
@@ -600,7 +713,7 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
Custom Scrollbars
-
+
.wb-body::-webkit-scrollbar {
width: 12px;
}
@@ -623,13 +736,15 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
.cloneNode(true)
});
- Run Code
-
+
+ Run Code
+
+
-
-
+
+
Custom Styles By Classname
-
+
.winbox.my-theme{
background: #fff;
}
@@ -650,13 +765,15 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
.cloneNode(true)
});
- Run Code
-
+
+ Run Code
+
+
-
-
+
+
Use Theme
-
+
<head>
<link rel="stylesheet" href="dist/css/winbox.min.css">
<link rel="stylesheet" href="dist/css/themes/modern.min.css">
@@ -669,13 +786,15 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
.cloneNode(true)
});
- Run Code
-
+
+ Run Code
+
+
-
-
+
+
Custom Controls
-
+
.wb-like {
background-size: 20px auto;
}
@@ -697,13 +816,15 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
}
});
- Run Code
-
+
+ Run Code
+
+
-
-
+
+
Custom Template (Layout)
-
+
.wb-custom {
background-image: url(demo/icon-github.svg);
background-size: 17px auto;
@@ -725,289 +846,291 @@ WinBox is a modern HTML5 window manager for the web. Lightweight, outstandin
new WinBox("Custom Template", { template });
- Run Code
-
-
-
-
-
-
+
+
+
Lorem Ipsum
-
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
-
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
-
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
-
-
-
Minimize (Toggle)
-
Maximize (Toggle)
-
Fullscreen (Toggle)
+
+ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
+ nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
+ sed diam voluptua. At vero eos et accusam et justo duo dolores et ea
+ rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem
+ ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur
+ sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et
+ dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam
+ et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea
+ takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit
+ amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor
+ invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
+ At vero eos et accusam et justo duo dolores et ea rebum. Stet clita
+ kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit
+ amet.
+
+
+ Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse
+ molestie consequat, vel illum dolore eu feugiat nulla facilisis at
+ vero eros et accumsan et iusto odio dignissim qui blandit praesent
+ luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam
+ nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat
+ volutpat.
+
+
+ Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper
+ suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem
+ vel eum iriure dolor in hendrerit in vulputate velit esse molestie
+ consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et
+ accumsan et iusto odio dignissim qui blandit praesent luptatum zzril
+ delenit augue duis dolore te feugait nulla facilisi.
+
+
+
+
+ Minimize (Toggle)
+
+
+ Maximize (Toggle)
+
+
+ Fullscreen (Toggle)
+
Modal (Toggle)
- Move (Center, Center)
+
+ Move (Center, Center)
+
Move (Right, Bottom)
Resize (50%, 50%)
Set Title
Set Color
Add Class (my-theme)
- Remove Class (my-theme)
+
+ Remove Class (my-theme)
+
Close
Force Close
+
-
-
-
+
-
+ hljs.highlightAll();
+
+
diff --git a/package.json b/package.json
index f3ed2fa..dcc74e5 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,9 @@
"build:bundle": "node task/build --bundle",
"build:svg": "node task/svgo",
"build": "npm run clean && npm run copy && npm run build:svg && npm run build:css && npm run build:css:bundle && npm run build:css:theme-modern && npm run build:css:theme-white && node task/bundle --style && npm run build:js && npm run build:bundle && echo Build Complete. && exit 0",
- "server": "node task/server.js"
+ "server": "node task/server.js",
+ "format": "prettier --write .",
+ "lint": "prettier --check . && eslint src/"
},
"files": [
"dist/",
@@ -50,16 +52,19 @@
"LICENSE"
],
"readme": "README.md",
- "dependencies": {},
"devDependencies": {
+ "@eslint/js": "^9.9.0",
"base64-img": "^1.0.4",
"cpx": "^1.5.0",
"csso": "^5.0.4",
"csso-cli": "^4.0.1",
+ "eslint": "^9.9.0",
+ "globals": "^15.9.0",
"google-closure-compiler": "^20220719.0.0",
"less": "^4.1.3",
"less-plugin-autoprefix": "^2.0.0",
"less-plugin-clean-css": "^1.5.1",
+ "prettier": "3.3.3",
"svgo": "^2.8.0",
"web-servo": "^0.5.1"
}
diff --git a/src/css/themes/modern.less b/src/css/themes/modern.less
index d66c66f..0845246 100644
--- a/src/css/themes/modern.less
+++ b/src/css/themes/modern.less
@@ -6,7 +6,7 @@
}
//&.min:not(:hover),
- &:not(.min,.focus) {
+ &:not(.min, .focus) {
background: #666;
}
@@ -44,7 +44,6 @@
}
.wb-body {
-
& {
/* width of window border: */
margin: 4px;
diff --git a/src/css/themes/white.less b/src/css/themes/white.less
index 23a0d10..30835e6 100644
--- a/src/css/themes/white.less
+++ b/src/css/themes/white.less
@@ -10,4 +10,4 @@
.wb-control {
filter: invert(1);
}
-}
\ No newline at end of file
+}
diff --git a/src/css/winbox.css b/src/css/winbox.css
index 9660acf..99d0441 100644
--- a/src/css/winbox.css
+++ b/src/css/winbox.css
@@ -3,9 +3,15 @@
left: 0;
top: 0;
background: #0050ff;
- box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
+ box-shadow:
+ 0 14px 28px rgba(0, 0, 0, 0.25),
+ 0 10px 10px rgba(0, 0, 0, 0.22);
/* using transform make contents blur when applied and requires more gpu memory */
- transition: width 0.3s, height 0.3s, left 0.3s, top 0.3s;
+ transition:
+ width 0.3s,
+ height 0.3s,
+ left 0.3s,
+ top 0.3s;
transition-timing-function: cubic-bezier(0.3, 1, 0.3, 1);
/* contain "strict" does not make overflow contents selectable */
contain: layout size;
@@ -236,7 +242,7 @@ body.wb-lock iframe {
pointer-events: none;
}
.winbox.modal:before {
- content: '';
+ content: "";
position: absolute;
top: 0;
left: 0;
@@ -246,7 +252,7 @@ body.wb-lock iframe {
border-radius: inherit;
}
.winbox.modal:after {
- content: '';
+ content: "";
position: absolute;
top: -50vh;
left: -50vw;
diff --git a/src/css/winbox.less b/src/css/winbox.less
index 897b765..67630d7 100644
--- a/src/css/winbox.less
+++ b/src/css/winbox.less
@@ -6,10 +6,16 @@
left: 0;
top: 0;
background: #0050ff;
- box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
+ box-shadow:
+ 0 14px 28px rgba(0, 0, 0, 0.25),
+ 0 10px 10px rgba(0, 0, 0, 0.22);
/* using transform make contents blur when applied and requires more gpu memory */
//transition: width .3s, height .3s, transform .3s;
- transition: width .3s, height .3s, left .3s, top .3s;
+ transition:
+ width 0.3s,
+ height 0.3s,
+ left 0.3s,
+ top 0.3s;
transition-timing-function: cubic-bezier(0.3, 1, 0.3, 1);
//transform-origin: bottom center;
/* contain "strict" does not make overflow contents selectable */
@@ -60,14 +66,14 @@ body > .wb-body{
}
*/
-.wb-drag{
+.wb-drag {
height: 100%;
padding-left: 10px;
cursor: move;
}
-.wb-title{
- font-family : Arial, sans-serif;
+.wb-title {
+ font-family: Arial, sans-serif;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
@@ -165,7 +171,7 @@ body > .wb-body{
z-index: 2;
}
-.wb-control{
+.wb-control {
float: right;
height: 100%;
max-width: 100%;
@@ -229,7 +235,7 @@ body > .wb-body{
.winbox.max .wb-body ~ div {
pointer-events: none;
}
-.winbox.max .wb-drag{
+.winbox.max .wb-drag {
cursor: default;
}
@@ -241,7 +247,7 @@ body > .wb-body{
.wb-drag {
cursor: default;
}
- .wb-body > *{
+ .wb-body > * {
display: none;
}
}
@@ -259,14 +265,14 @@ body > .wb-body{
margin: 0 !important;
}
-.winbox iframe{
+.winbox iframe {
position: absolute;
width: 100%;
height: 100%;
border: 0;
}
-body.wb-lock .winbox{
+body.wb-lock .winbox {
will-change: left, top, width, height;
transition: none;
}
@@ -274,9 +280,9 @@ body.wb-lock iframe {
pointer-events: none;
}
-.winbox.modal{
- &:before{
- content: '';
+.winbox.modal {
+ &:before {
+ content: "";
position: absolute;
top: 0;
left: 0;
@@ -285,8 +291,8 @@ body.wb-lock iframe {
background: inherit;
border-radius: inherit;
}
- &:after{
- content: '';
+ &:after {
+ content: "";
position: absolute;
top: -50vh;
left: -50vw;
@@ -298,16 +304,16 @@ body.wb-lock iframe {
}
.wb-min,
.wb-max,
- .wb-full{
+ .wb-full {
display: none;
}
}
@keyframes wb-fade-in {
- 0%{
+ 0% {
opacity: 0;
}
- 100%{
+ 100% {
opacity: 0.85;
}
}
diff --git a/src/js/helper.js b/src/js/helper.js
index d664789..772761d 100644
--- a/src/js/helper.js
+++ b/src/js/helper.js
@@ -5,9 +5,8 @@
* @param {AddEventListenerOptions|boolean=} opt
*/
-export function addListener(node, event, fn, opt){
-
- node && node.addEventListener(event, fn, opt || false);
+export function addListener(node, event, fn, opt) {
+ node && node.addEventListener(event, fn, opt || false);
}
/**
@@ -17,9 +16,8 @@ export function addListener(node, event, fn, opt){
* @param {AddEventListenerOptions|boolean=} opt
*/
-export function removeListener(node, event, fn, opt){
-
- node && node.removeEventListener(event, fn, opt || false);
+export function removeListener(node, event, fn, opt) {
+ node && node.removeEventListener(event, fn, opt || false);
}
/**
@@ -27,68 +25,56 @@ export function removeListener(node, event, fn, opt){
* @param {boolean=} prevent
*/
-export function preventEvent(event, prevent){
+export function preventEvent(event, prevent) {
+ event.stopPropagation();
+ prevent && /*event.cancelable &&*/ event.preventDefault();
- event.stopPropagation();
- prevent && /*event.cancelable &&*/ event.preventDefault();
-
- //event.stopImmediatePropagation();
- //event.returnValue = false;
+ //event.stopImmediatePropagation();
+ //event.returnValue = false;
}
-export function getByClass(root, name){
-
- return root.getElementsByClassName(name)[0];
+export function getByClass(root, name) {
+ return root.getElementsByClassName(name)[0];
}
-export function addClass(node, classname){
-
- node.classList.add(classname);
+export function addClass(node, classname) {
+ node.classList.add(classname);
}
-export function hasClass(node, classname){
-
- return node.classList.contains(classname);
+export function hasClass(node, classname) {
+ return node.classList.contains(classname);
}
-export function removeClass(node, classname){
-
- node.classList.remove(classname);
+export function removeClass(node, classname) {
+ node.classList.remove(classname);
}
-export function setStyle(node, style, value){
+export function setStyle(node, style, value) {
+ value = "" + value;
- value = "" + value;
-
- if(node["_s_" + style] !== value){
-
- node.style.setProperty(style, value);
- node["_s_" + style] = value;
- }
+ if (node["_s_" + style] !== value) {
+ node.style.setProperty(style, value);
+ node["_s_" + style] = value;
+ }
}
-export function setAttribute(node, key, value){
-
- value = "" + value;
-
- if(node["_a_" + key] !== value){
+export function setAttribute(node, key, value) {
+ value = "" + value;
- node.setAttribute(key, value);
- node["_a_" + key] = value;
- }
+ if (node["_a_" + key] !== value) {
+ node.setAttribute(key, value);
+ node["_a_" + key] = value;
+ }
}
-export function removeAttribute(node, key){
-
- if(node["_a_" + key] !== null){
-
- node.removeAttribute(key);
- node["_a_" + key] = null;
- }
+export function removeAttribute(node, key) {
+ if (node["_a_" + key] !== null) {
+ node.removeAttribute(key);
+ node["_a_" + key] = null;
+ }
}
-export function setText(node, value){
-
- const textnode = node.firstChild;
- textnode ? textnode.nodeValue = value : node.textContent = value;
+export function setText(node, value) {
+ const textnode = node.firstChild;
+ textnode ? (textnode.nodeValue = value) : (node.textContent = value);
}
diff --git a/src/js/template.js b/src/js/template.js
index 8a706d2..fb13c62 100644
--- a/src/js/template.js
+++ b/src/js/template.js
@@ -2,42 +2,38 @@
@type null|HTMLDivElement
*/
let template = null;
-const templateHTML = (
+const templateHTML =
+ //'
' +
- //'
' +
+ "" +
+ "
" +
+ "
" +
+ "
" +
+ "
" +
+ "
" +
+ "
" +
+ "
" +
+ "
" +
+ "
";
- '' +
+//'
'
- '
' +
+export default function (tpl) {
+ if (!template) {
+ template = document.createElement("div");
+ template.innerHTML = templateHTML;
+ }
- '
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '
' +
- '
'
-
- //'
'
-);
-
-export default function(tpl){
- if (!template) {
- template = document.createElement('div');
- template.innerHTML = templateHTML;
- }
-
- return (tpl || template).cloneNode(true);
+ return (tpl || template).cloneNode(true);
}
diff --git a/src/js/winbox.js b/src/js/winbox.js
index dba4963..f8c6251 100644
--- a/src/js/winbox.js
+++ b/src/js/winbox.js
@@ -9,7 +9,17 @@
// TODO: rename control amd state classes (min, max, modal, focus, ...) #62
import template from "./template.js";
-import { addListener, removeListener, setStyle, setText, getByClass, addClass, removeClass, hasClass, preventEvent } from "./helper.js";
+import {
+ addListener,
+ removeListener,
+ setStyle,
+ setText,
+ getByClass,
+ addClass,
+ removeClass,
+ hasClass,
+ preventEvent,
+} from "./helper.js";
//const ios = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window["MSStream"];
@@ -17,8 +27,8 @@ const use_raf = false;
const stack_min = [];
const stack_win = [];
// use passive for touch and mouse wheel
-const eventOptions = { "capture": true, "passive": false };
-const eventOptionsPassive = { "capture": true, "passive": true };
+const eventOptions = { capture: true, passive: false };
+const eventOptionsPassive = { capture: true, passive: true };
let body;
let id_counter = 0;
let index_counter = 10;
@@ -35,295 +45,271 @@ let window_clicked;
* @this WinBox
*/
-function WinBox(params, _title){
-
- if(!(this instanceof WinBox)) {
-
- return new WinBox(params);
- }
-
- body || setup();
-
- let id,
- index,
- root,
- tpl,
- title,
- icon,
- mount,
- html,
- url,
-
- width,
- height,
- minwidth,
- minheight,
- maxwidth,
- maxheight,
- autosize,
- overflow,
-
- x,
- y,
-
- top,
- left,
- bottom,
- right,
-
- min,
- max,
- hidden,
- modal,
-
- background,
- border,
- header,
- classname,
-
- oncreate,
- onclose,
- onfocus,
- onblur,
- onmove,
- onresize,
- onfullscreen,
- onmaximize,
- onminimize,
- onrestore,
- onhide,
- onshow,
- onload;
-
- if(params){
-
- if(_title){
-
- title = params;
- params = _title;
- }
-
- if(typeof params === "string"){
-
- title = params;
- }
- else{
-
- id = params["id"];
- index = params["index"];
- root = params["root"];
- tpl = params["template"];
- title = title || params["title"];
- icon = params["icon"];
- mount = params["mount"];
- html = params["html"];
- url = params["url"];
-
- width = params["width"];
- height = params["height"];
- minwidth = params["minwidth"];
- minheight = params["minheight"];
- maxwidth = params["maxwidth"];
- maxheight = params["maxheight"];
- autosize = params["autosize"];
- overflow = params["overflow"];
-
- min = params["min"];
- max = params["max"];
- hidden = params["hidden"];
- modal = params["modal"];
-
- x = params["x"] || (modal ? "center" : 0);
- y = params["y"] || (modal ? "center" : 0);
-
- top = params["top"];
- left = params["left"];
- bottom = params["bottom"];
- right = params["right"];
-
- background = params["background"];
- border = params["border"];
- header = params["header"];
- classname = params["class"];
-
- oncreate = params["oncreate"];
- onclose = params["onclose"];
- onfocus = params["onfocus"];
- onblur = params["onblur"];
- onmove = params["onmove"];
- onresize = params["onresize"];
- onfullscreen = params["onfullscreen"];
- onmaximize = params["onmaximize"];
- onminimize = params["onminimize"];
- onrestore = params["onrestore"];
- onhide = params["onhide"];
- onshow = params["onshow"];
- onload = params["onload"];
- }
- }
-
- this.dom = template(tpl);
- this.dom.id = this.id = id || ("winbox-" + (++id_counter));
- this.dom.className = "winbox" + (classname ? " " + (typeof classname === "string" ? classname : classname.join(" ")) : "") + (modal ? " modal" : "");
- this.dom["winbox"] = this;
- this.window = this.dom;
- this.body = getByClass(this.dom, "wb-body");
- this.header = header || 35;
- //this.plugins = [];
-
- stack_win.push(this);
-
- if(background){
-
- this.setBackground(background);
- }
-
- if(border){
-
- setStyle(this.body, "margin", border + (isNaN(border) ? "" : "px"));
- }
- else{
-
- border = 0;
- }
-
- if(header){
-
- const node = getByClass(this.dom, "wb-header");
- setStyle(node, "height", header + "px");
- setStyle(node, "line-height", header + "px");
- setStyle(this.body, "top", header + "px");
- }
-
- if(title){
-
- this.setTitle(title);
- }
-
- if(icon){
-
- this.setIcon(icon);
- }
-
- if(mount){
-
- this.mount(mount);
- }
- else if(html){
-
- this.body.innerHTML = html;
- }
- else if(url){
-
- this.setUrl(url, onload);
- }
-
- top = top ? parse(top, root_h) : 0;
- bottom = bottom ? parse(bottom, root_h) : 0;
- left = left ? parse(left, root_w) : 0;
- right = right ? parse(right, root_w) : 0;
-
- const viewport_w = root_w - left - right;
- const viewport_h = root_h - top - bottom;
-
- maxwidth = maxwidth ? parse(maxwidth, viewport_w) : viewport_w;
- maxheight = maxheight ? parse(maxheight, viewport_h) : viewport_h;
- minwidth = minwidth ? parse(minwidth, maxwidth) : 150;
- minheight = minheight ? parse(minheight, maxheight) : this.header;
-
- if(autosize){
-
- (root || body).appendChild(this.body);
-
- width = Math.max(Math.min(this.body.clientWidth + border * 2 + 1, maxwidth), minwidth);
- height = Math.max(Math.min(this.body.clientHeight + this.header + border + 1, maxheight), minheight);
-
- this.dom.appendChild(this.body);
+function WinBox(params, _title) {
+ if (!(this instanceof WinBox)) {
+ return new WinBox(params);
+ }
+
+ body || setup();
+
+ let id,
+ index,
+ root,
+ tpl,
+ title,
+ icon,
+ mount,
+ html,
+ url,
+ width,
+ height,
+ minwidth,
+ minheight,
+ maxwidth,
+ maxheight,
+ autosize,
+ overflow,
+ x,
+ y,
+ top,
+ left,
+ bottom,
+ right,
+ min,
+ max,
+ hidden,
+ modal,
+ background,
+ border,
+ header,
+ classname,
+ oncreate,
+ onclose,
+ onfocus,
+ onblur,
+ onmove,
+ onresize,
+ onfullscreen,
+ onmaximize,
+ onminimize,
+ onrestore,
+ onhide,
+ onshow,
+ onload;
+
+ if (params) {
+ if (_title) {
+ title = params;
+ params = _title;
}
- else{
- width = width ? parse(width, maxwidth) : Math.max(maxwidth / 2, minwidth) | 0;
- height = height ? parse(height, maxheight) : Math.max(maxheight / 2, minheight) | 0;
+ if (typeof params === "string") {
+ title = params;
+ } else {
+ id = params["id"];
+ index = params["index"];
+ root = params["root"];
+ tpl = params["template"];
+ title = title || params["title"];
+ icon = params["icon"];
+ mount = params["mount"];
+ html = params["html"];
+ url = params["url"];
+
+ width = params["width"];
+ height = params["height"];
+ minwidth = params["minwidth"];
+ minheight = params["minheight"];
+ maxwidth = params["maxwidth"];
+ maxheight = params["maxheight"];
+ autosize = params["autosize"];
+ overflow = params["overflow"];
+
+ min = params["min"];
+ max = params["max"];
+ hidden = params["hidden"];
+ modal = params["modal"];
+
+ x = params["x"] || (modal ? "center" : 0);
+ y = params["y"] || (modal ? "center" : 0);
+
+ top = params["top"];
+ left = params["left"];
+ bottom = params["bottom"];
+ right = params["right"];
+
+ background = params["background"];
+ border = params["border"];
+ header = params["header"];
+ classname = params["class"];
+
+ oncreate = params["oncreate"];
+ onclose = params["onclose"];
+ onfocus = params["onfocus"];
+ onblur = params["onblur"];
+ onmove = params["onmove"];
+ onresize = params["onresize"];
+ onfullscreen = params["onfullscreen"];
+ onmaximize = params["onmaximize"];
+ onminimize = params["onminimize"];
+ onrestore = params["onrestore"];
+ onhide = params["onhide"];
+ onshow = params["onshow"];
+ onload = params["onload"];
}
+ }
+
+ this.dom = template(tpl);
+ this.dom.id = this.id = id || "winbox-" + ++id_counter;
+ this.dom.className =
+ "winbox" +
+ (classname
+ ? " " + (typeof classname === "string" ? classname : classname.join(" "))
+ : "") +
+ (modal ? " modal" : "");
+ this.dom["winbox"] = this;
+ this.window = this.dom;
+ this.body = getByClass(this.dom, "wb-body");
+ this.header = header || 35;
+ //this.plugins = [];
+
+ stack_win.push(this);
+
+ if (background) {
+ this.setBackground(background);
+ }
+
+ if (border) {
+ setStyle(this.body, "margin", border + (isNaN(border) ? "" : "px"));
+ } else {
+ border = 0;
+ }
+
+ if (header) {
+ const node = getByClass(this.dom, "wb-header");
+ setStyle(node, "height", header + "px");
+ setStyle(node, "line-height", header + "px");
+ setStyle(this.body, "top", header + "px");
+ }
+
+ if (title) {
+ this.setTitle(title);
+ }
+
+ if (icon) {
+ this.setIcon(icon);
+ }
+
+ if (mount) {
+ this.mount(mount);
+ } else if (html) {
+ this.body.innerHTML = html;
+ } else if (url) {
+ this.setUrl(url, onload);
+ }
+
+ top = top ? parse(top, root_h) : 0;
+ bottom = bottom ? parse(bottom, root_h) : 0;
+ left = left ? parse(left, root_w) : 0;
+ right = right ? parse(right, root_w) : 0;
+
+ const viewport_w = root_w - left - right;
+ const viewport_h = root_h - top - bottom;
+
+ maxwidth = maxwidth ? parse(maxwidth, viewport_w) : viewport_w;
+ maxheight = maxheight ? parse(maxheight, viewport_h) : viewport_h;
+ minwidth = minwidth ? parse(minwidth, maxwidth) : 150;
+ minheight = minheight ? parse(minheight, maxheight) : this.header;
+
+ if (autosize) {
+ (root || body).appendChild(this.body);
+
+ width = Math.max(
+ Math.min(this.body.clientWidth + border * 2 + 1, maxwidth),
+ minwidth
+ );
+ height = Math.max(
+ Math.min(this.body.clientHeight + this.header + border + 1, maxheight),
+ minheight
+ );
- x = x ? parse(x, viewport_w, width) : left;
- y = y ? parse(y, viewport_h, height) : top;
-
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
- this.minwidth = minwidth;
- this.minheight = minheight;
- this.maxwidth = maxwidth;
- this.maxheight = maxheight;
- this.top = top;
- this.right = right;
- this.bottom = bottom;
- this.left = left;
+ this.dom.appendChild(this.body);
+ } else {
+ width = width
+ ? parse(width, maxwidth)
+ : Math.max(maxwidth / 2, minwidth) | 0;
+ height = height
+ ? parse(height, maxheight)
+ : Math.max(maxheight / 2, minheight) | 0;
+ }
+
+ x = x ? parse(x, viewport_w, width) : left;
+ y = y ? parse(y, viewport_h, height) : top;
+
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ this.minwidth = minwidth;
+ this.minheight = minheight;
+ this.maxwidth = maxwidth;
+ this.maxheight = maxheight;
+ this.top = top;
+ this.right = right;
+ this.bottom = bottom;
+ this.left = left;
+ this.index = index;
+ this.overflow = overflow;
+ //this.border = border;
+ this.min = false;
+ this.max = false;
+ this.full = false;
+ this.hidden = false;
+ this.focused = false;
+
+ this.onclose = onclose;
+ this.onfocus = onfocus;
+ this.onblur = onblur;
+ this.onmove = onmove;
+ this.onresize = onresize;
+ this.onfullscreen = onfullscreen;
+ this.onmaximize = onmaximize;
+ this.onminimize = onminimize;
+ this.onrestore = onrestore;
+ this.onhide = onhide;
+ this.onshow = onshow;
+
+ if (hidden) {
+ this.hide();
+ } else {
+ this.focus();
+ }
+
+ if (index || index === 0) {
this.index = index;
- this.overflow = overflow;
- //this.border = border;
- this.min = false;
- this.max = false;
- this.full = false;
- this.hidden = false;
- this.focused = false;
-
- this.onclose = onclose;
- this.onfocus = onfocus;
- this.onblur = onblur;
- this.onmove = onmove;
- this.onresize = onresize;
- this.onfullscreen = onfullscreen;
- this.onmaximize = onmaximize;
- this.onminimize = onminimize;
- this.onrestore = onrestore;
- this.onhide = onhide;
- this.onshow = onshow;
-
- if(hidden){
-
- this.hide();
- }
- else{
-
- this.focus();
- }
-
- if(index || (index === 0)){
-
- this.index = index;
- setStyle(this.dom, "z-index", index);
- if(index > index_counter) index_counter = index;
- }
-
- if(max){
-
- this.maximize();
- }
- else if(min){
-
- this.minimize();
- }
- else{
-
- this.resize().move();
- }
-
- register(this);
- (root || body).appendChild(this.dom);
- oncreate && oncreate.call(this, params);
+ setStyle(this.dom, "z-index", index);
+ if (index > index_counter) index_counter = index;
+ }
+
+ if (max) {
+ this.maximize();
+ } else if (min) {
+ this.minimize();
+ } else {
+ this.resize().move();
+ }
+
+ register(this);
+ (root || body).appendChild(this.dom);
+ oncreate && oncreate.call(this, params);
}
-WinBox["new"] = function(params){
-
- return new WinBox(params);
+WinBox["new"] = function (params) {
+ return new WinBox(params);
};
-WinBox["stack"] = function(){
-
- return stack_win;
+WinBox["stack"] = function () {
+ return stack_win;
};
export default WinBox;
@@ -335,204 +321,189 @@ export default WinBox;
* @return number
*/
-function parse(num, base, center){
-
- if(typeof num === "string"){
-
- if(num === "center"){
-
- num = ((base - center) / 2 + 0.5) | 0;
- }
- else if(num === "right" || num === "bottom"){
-
- num = (base - center);
- }
- else{
-
- const value = parseFloat(num);
- const unit = (("" + value) !== num) && num.substring(("" + value).length);
-
- if(unit === "%"){
-
- num = (base / 100 * value + 0.5) | 0;
- }
- else{
-
- num = value;
- }
- }
+function parse(num, base, center) {
+ if (typeof num === "string") {
+ if (num === "center") {
+ num = ((base - center) / 2 + 0.5) | 0;
+ } else if (num === "right" || num === "bottom") {
+ num = base - center;
+ } else {
+ const value = parseFloat(num);
+ const unit = "" + value !== num && num.substring(("" + value).length);
+
+ if (unit === "%") {
+ num = ((base / 100) * value + 0.5) | 0;
+ } else {
+ num = value;
+ }
}
+ }
- return num;
+ return num;
}
-function setup(){
+function setup() {
+ body = document.body;
- body = document.body;
-
- body[prefix_request = "requestFullscreen"] ||
- body[prefix_request = "msRequestFullscreen"] ||
- body[prefix_request = "webkitRequestFullscreen"] ||
- body[prefix_request = "mozRequestFullscreen"] ||
+ body[(prefix_request = "requestFullscreen")] ||
+ body[(prefix_request = "msRequestFullscreen")] ||
+ body[(prefix_request = "webkitRequestFullscreen")] ||
+ body[(prefix_request = "mozRequestFullscreen")] ||
(prefix_request = "");
- prefix_exit = prefix_request && (
-
- prefix_request.replace("request", "exit")
- .replace("mozRequest", "mozCancel")
- .replace("Request", "Exit")
- );
-
- addListener(window, "resize", function(){
-
- init();
- update_min_stack();
-
- // TODO adjust window sizes #151
-
- // for(let i = 0; i < stack_win.length; i++){
- //
- // stack_win[i].resize().move();
- // }
- });
-
- addListener(body, "mousedown", function(event){
-
- window_clicked = false;
-
- }, true);
+ prefix_exit =
+ prefix_request &&
+ prefix_request
+ .replace("request", "exit")
+ .replace("mozRequest", "mozCancel")
+ .replace("Request", "Exit");
- addListener(body, "mousedown", function(event){
-
- if(!window_clicked){
-
- const stack_length = stack_win.length;
-
- if(stack_length){
-
- for(let i = stack_length - 1; i >= 0; i--){
-
- const last_focus = stack_win[i];
+ addListener(window, "resize", function () {
+ init();
+ update_min_stack();
- if(last_focus.focused){
+ // TODO adjust window sizes #151
- last_focus.blur();
- break;
- }
- }
- }
+ // for(let i = 0; i < stack_win.length; i++){
+ //
+ // stack_win[i].resize().move();
+ // }
+ });
+
+ addListener(
+ body,
+ "mousedown",
+ function () {
+ window_clicked = false;
+ },
+ true
+ );
+
+ addListener(body, "mousedown", function () {
+ if (!window_clicked) {
+ const stack_length = stack_win.length;
+
+ if (stack_length) {
+ for (let i = stack_length - 1; i >= 0; i--) {
+ const last_focus = stack_win[i];
+
+ if (last_focus.focused) {
+ last_focus.blur();
+ break;
+ }
}
- });
+ }
+ }
+ });
- init();
+ init();
}
/**
* @param {WinBox} self
*/
-function register(self){
-
- addWindowListener(self, "drag");
- addWindowListener(self, "n");
- addWindowListener(self, "s");
- addWindowListener(self, "w");
- addWindowListener(self, "e");
- addWindowListener(self, "nw");
- addWindowListener(self, "ne");
- addWindowListener(self, "se");
- addWindowListener(self, "sw");
-
- addListener(getByClass(self.dom, "wb-min"), "click", function(event){
-
- preventEvent(event);
- self.min ? self.restore().focus() : self.minimize();
- });
-
- addListener(getByClass(self.dom, "wb-max"), "click", function(event){
-
- preventEvent(event);
- self.max ? self.restore().focus() : self.maximize().focus();
+function register(self) {
+ addWindowListener(self, "drag");
+ addWindowListener(self, "n");
+ addWindowListener(self, "s");
+ addWindowListener(self, "w");
+ addWindowListener(self, "e");
+ addWindowListener(self, "nw");
+ addWindowListener(self, "ne");
+ addWindowListener(self, "se");
+ addWindowListener(self, "sw");
+
+ addListener(getByClass(self.dom, "wb-min"), "click", function (event) {
+ preventEvent(event);
+ self.min ? self.restore().focus() : self.minimize();
+ });
+
+ addListener(getByClass(self.dom, "wb-max"), "click", function (event) {
+ preventEvent(event);
+ self.max ? self.restore().focus() : self.maximize().focus();
+ });
+
+ if (prefix_request) {
+ addListener(getByClass(self.dom, "wb-full"), "click", function (event) {
+ preventEvent(event);
+ self.fullscreen().focus();
});
-
- if(prefix_request){
-
- addListener(getByClass(self.dom, "wb-full"), "click", function(event){
-
- preventEvent(event);
- self.fullscreen().focus();
- });
- }
- else{
-
- self.addClass("no-full");
- }
-
- addListener(getByClass(self.dom, "wb-close"), "click", function(event){
-
- preventEvent(event);
- self.close() || (self = null);
- });
-
- addListener(self.dom, "mousedown", function(event){
-
- window_clicked = true;
-
- }, true);
-
- addListener(self.body, "mousedown", function(event){
-
- // stop propagation would disable global listeners used inside window contents
- // use event bubbling for this listener to skip this handler by the other click listeners
- self.focus();
-
- }, true);
+ } else {
+ self.addClass("no-full");
+ }
+
+ addListener(getByClass(self.dom, "wb-close"), "click", function (event) {
+ preventEvent(event);
+ self.close() || (self = null);
+ });
+
+ addListener(
+ self.dom,
+ "mousedown",
+ function () {
+ window_clicked = true;
+ },
+ true
+ );
+
+ addListener(
+ self.body,
+ "mousedown",
+ function () {
+ // stop propagation would disable global listeners used inside window contents
+ // use event bubbling for this listener to skip this handler by the other click listeners
+ self.focus();
+ },
+ true
+ );
}
/**
* @param {WinBox} self
*/
-function remove_min_stack(self){
-
- stack_min.splice(stack_min.indexOf(self), 1);
- update_min_stack();
- self.removeClass("min");
- self.min = false;
- self.dom.title = "";
+function remove_min_stack(self) {
+ stack_min.splice(stack_min.indexOf(self), 1);
+ update_min_stack();
+ self.removeClass("min");
+ self.min = false;
+ self.dom.title = "";
}
-function update_min_stack(){
+function update_min_stack() {
+ const length = stack_min.length;
+ const splitscreen_index = {};
+ const splitscreen_length = {};
- const length = stack_min.length;
- const splitscreen_index = {};
- const splitscreen_length = {};
+ for (let i = 0, self, key; i < length; i++) {
+ self = stack_min[i];
+ key = self.left + ":" + self.top;
- for(let i = 0, self, key; i < length; i++){
-
- self = stack_min[i];
- key = self.left + ":" + self.top;
-
- if(splitscreen_length[key]){
-
- splitscreen_length[key]++;
- }
- else{
-
- splitscreen_index[key] = 0;
- splitscreen_length[key] = 1;
- }
- }
-
- for(let i = 0, self, key, width; i < length; i++){
-
- self = stack_min[i]
- key = self.left + ":" + self.top;
- width = Math.min((root_w - self.left - self.right) / splitscreen_length[key], 250);
- self.resize((width + 1) | 0, self.header, true)
- .move((self.left + splitscreen_index[key] * width) | 0, root_h - self.bottom - self.header, true);
- splitscreen_index[key]++;
+ if (splitscreen_length[key]) {
+ splitscreen_length[key]++;
+ } else {
+ splitscreen_index[key] = 0;
+ splitscreen_length[key] = 1;
}
+ }
+
+ for (let i = 0, self, key, width; i < length; i++) {
+ self = stack_min[i];
+ key = self.left + ":" + self.top;
+ width = Math.min(
+ (root_w - self.left - self.right) / splitscreen_length[key],
+ 250
+ );
+ self
+ .resize((width + 1) | 0, self.header, true)
+ .move(
+ (self.left + splitscreen_index[key] * width) | 0,
+ root_h - self.bottom - self.header,
+ true
+ );
+ splitscreen_index[key]++;
+ }
}
/**
@@ -540,270 +511,263 @@ function update_min_stack(){
* @param {string} dir
*/
-function addWindowListener(self, dir){
-
- const node = getByClass(self.dom, "wb-" + dir);
- if(!node) return;
+function addWindowListener(self, dir) {
+ const node = getByClass(self.dom, "wb-" + dir);
+ if (!node) return;
- let touch, x, y;
- let raf_timer, raf_move, raf_resize;
- let dblclick_timer = 0;
+ let touch, x, y;
+ let raf_timer, raf_move, raf_resize;
+ let dblclick_timer = 0;
- addListener(node, "mousedown", mousedown, eventOptions);
- addListener(node, "touchstart", mousedown, eventOptions);
+ addListener(node, "mousedown", mousedown, eventOptions);
+ addListener(node, "touchstart", mousedown, eventOptions);
- function loop(){
+ function loop() {
+ raf_timer = requestAnimationFrame(loop);
- raf_timer = requestAnimationFrame(loop);
-
- if(raf_resize){
-
- self.resize();
- raf_resize = false;
- }
-
- if(raf_move){
-
- self.move();
- raf_move = false;
- }
+ if (raf_resize) {
+ self.resize();
+ raf_resize = false;
}
- function mousedown(event){
-
- // prevent the full iteration through the fallback chain of a touch event (touch > mouse > click)
- preventEvent(event, true);
- //window_clicked = true;
- self.focus();
-
- if(dir === "drag"){
-
- if(self.min){
-
- self.restore();
- return;
- }
-
- if(!self.hasClass("no-max")){
-
- const now = Date.now();
- const diff = now - dblclick_timer;
-
- dblclick_timer = now;
-
- if(diff < 300){
-
- self.max ? self.restore() : self.maximize();
- return;
- }
- }
- }
-
- if(/*!self.max &&*/ !self.min){
-
- addClass(body, "wb-lock");
- use_raf && loop();
-
- if((touch = event.touches) && (touch = touch[0])){
-
- event = touch;
-
- // TODO: fix when touch events bubbles up to the document body
- //addListener(self.dom, "touchmove", preventEvent);
- addListener(window, "touchmove", handler_mousemove, eventOptionsPassive);
- addListener(window, "touchend", handler_mouseup, eventOptionsPassive);
- }
- else{
-
- //addListener(this, "mouseleave", handler_mouseup);
- addListener(window, "mousemove", handler_mousemove, eventOptionsPassive);
- addListener(window, "mouseup", handler_mouseup, eventOptionsPassive);
- }
-
- x = event.pageX;
- y = event.pageY;
-
- // appearing scrollbars on the root element does not trigger "window.onresize",
- // force refresh window size via init(), also force layout recalculation (layout trashing)
- // it is probably very rare that the body overflow changes between window open and close
-
- //init();
- }
+ if (raf_move) {
+ self.move();
+ raf_move = false;
}
+ }
- function handler_mousemove(event){
-
- preventEvent(event);
-
- if(touch){
-
- event = event.touches[0];
- }
-
- const pageX = event.pageX;
- const pageY = event.pageY;
- const offsetX = pageX - x;
- const offsetY = pageY - y;
-
- const old_w = self.width;
- const old_h = self.height;
- const old_x = self.x;
- const old_y = self.y;
-
- let resize_w, resize_h, move_x, move_y;
-
- if(dir === "drag"){
-
- if(self.hasClass("no-move")) return;
-
- self.x += offsetX;
- self.y += offsetY;
- move_x = move_y = 1;
- }
- else{
-
- if(dir === "e" || dir === "se" || dir === "ne"){
-
- self.width += offsetX;
- resize_w = 1;
- }
- else if(dir === "w" || dir === "sw" || dir === "nw"){
-
- self.x += offsetX;
- self.width -= offsetX;
- resize_w = 1;
- move_x = 1;
- }
-
- if(dir === "s" || dir === "se" || dir === "sw"){
-
- self.height += offsetY;
- resize_h = 1;
- }
- else if(dir === "n" || dir === "ne" || dir === "nw"){
-
- self.y += offsetY;
- self.height -= offsetY;
- resize_h = 1;
- move_y = 1;
- }
- }
-
- if(resize_w){
-
- self.width = Math.max(Math.min(self.width, self.maxwidth, root_w - self.x - self.right), self.minwidth);
- resize_w = self.width !== old_w;
- }
+ function mousedown(event) {
+ // prevent the full iteration through the fallback chain of a touch event (touch > mouse > click)
+ preventEvent(event, true);
+ //window_clicked = true;
+ self.focus();
- if(resize_h){
+ if (dir === "drag") {
+ if (self.min) {
+ self.restore();
+ return;
+ }
- self.height = Math.max(Math.min(self.height, self.maxheight, root_h - self.y - self.bottom), self.minheight);
- resize_h = self.height !== old_h;
- }
+ if (!self.hasClass("no-max")) {
+ const now = Date.now();
+ const diff = now - dblclick_timer;
- if(resize_w || resize_h){
+ dblclick_timer = now;
- use_raf ? raf_resize = true : self.resize();
+ if (diff < 300) {
+ self.max ? self.restore() : self.maximize();
+ return;
}
+ }
+ }
- if(move_x){
-
- if(self.max){
-
- self.x = (
-
- pageX < root_w / 3 ?
-
- self.left
- :
- pageX > root_w / 3 * 2 ?
-
- root_w - self.width - self.right
- :
- root_w / 2 - self.width / 2
-
- ) + offsetX;
- }
+ if (/*!self.max &&*/ !self.min) {
+ addClass(body, "wb-lock");
+ use_raf && loop();
- self.x = Math.max(Math.min(self.x, self.overflow ? root_w - 30 : root_w - self.width - self.right), self.overflow ? 30 - self.width : self.left);
- move_x = self.x !== old_x;
- }
+ if ((touch = event.touches) && (touch = touch[0])) {
+ event = touch;
- if(move_y){
-
- if(self.max){
+ // TODO: fix when touch events bubbles up to the document body
+ //addListener(self.dom, "touchmove", preventEvent);
+ addListener(
+ window,
+ "touchmove",
+ handler_mousemove,
+ eventOptionsPassive
+ );
+ addListener(window, "touchend", handler_mouseup, eventOptionsPassive);
+ } else {
+ //addListener(this, "mouseleave", handler_mouseup);
+ addListener(
+ window,
+ "mousemove",
+ handler_mousemove,
+ eventOptionsPassive
+ );
+ addListener(window, "mouseup", handler_mouseup, eventOptionsPassive);
+ }
- self.y = self.top + offsetY;
- }
+ x = event.pageX;
+ y = event.pageY;
- self.y = Math.max(Math.min(self.y, self.overflow ? root_h - self.header : root_h - self.height - self.bottom), self.top);
- move_y = self.y !== old_y;
- }
+ // appearing scrollbars on the root element does not trigger "window.onresize",
+ // force refresh window size via init(), also force layout recalculation (layout trashing)
+ // it is probably very rare that the body overflow changes between window open and close
- if(move_x || move_y){
+ //init();
+ }
+ }
- if(self.max){
+ function handler_mousemove(event) {
+ preventEvent(event);
- self.restore();
- }
+ if (touch) {
+ event = event.touches[0];
+ }
- use_raf ? raf_move = true : self.move();
- }
+ const pageX = event.pageX;
+ const pageY = event.pageY;
+ const offsetX = pageX - x;
+ const offsetY = pageY - y;
+
+ const old_w = self.width;
+ const old_h = self.height;
+ const old_x = self.x;
+ const old_y = self.y;
+
+ let resize_w, resize_h, move_x, move_y;
+
+ if (dir === "drag") {
+ if (self.hasClass("no-move")) return;
+
+ self.x += offsetX;
+ self.y += offsetY;
+ move_x = move_y = 1;
+ } else {
+ if (dir === "e" || dir === "se" || dir === "ne") {
+ self.width += offsetX;
+ resize_w = 1;
+ } else if (dir === "w" || dir === "sw" || dir === "nw") {
+ self.x += offsetX;
+ self.width -= offsetX;
+ resize_w = 1;
+ move_x = 1;
+ }
+
+ if (dir === "s" || dir === "se" || dir === "sw") {
+ self.height += offsetY;
+ resize_h = 1;
+ } else if (dir === "n" || dir === "ne" || dir === "nw") {
+ self.y += offsetY;
+ self.height -= offsetY;
+ resize_h = 1;
+ move_y = 1;
+ }
+ }
- if(resize_w || move_x){
+ if (resize_w) {
+ self.width = Math.max(
+ Math.min(self.width, self.maxwidth, root_w - self.x - self.right),
+ self.minwidth
+ );
+ resize_w = self.width !== old_w;
+ }
- x = pageX;
- }
+ if (resize_h) {
+ self.height = Math.max(
+ Math.min(self.height, self.maxheight, root_h - self.y - self.bottom),
+ self.minheight
+ );
+ resize_h = self.height !== old_h;
+ }
- if(resize_h || move_y){
+ if (resize_w || resize_h) {
+ use_raf ? (raf_resize = true) : self.resize();
+ }
- y = pageY;
- }
+ if (move_x) {
+ if (self.max) {
+ self.x =
+ (pageX < root_w / 3
+ ? self.left
+ : pageX > (root_w / 3) * 2
+ ? root_w - self.width - self.right
+ : root_w / 2 - self.width / 2) + offsetX;
+ }
+
+ self.x = Math.max(
+ Math.min(
+ self.x,
+ self.overflow ? root_w - 30 : root_w - self.width - self.right
+ ),
+ self.overflow ? 30 - self.width : self.left
+ );
+ move_x = self.x !== old_x;
}
- function handler_mouseup(event){
+ if (move_y) {
+ if (self.max) {
+ self.y = self.top + offsetY;
+ }
+
+ self.y = Math.max(
+ Math.min(
+ self.y,
+ self.overflow
+ ? root_h - self.header
+ : root_h - self.height - self.bottom
+ ),
+ self.top
+ );
+ move_y = self.y !== old_y;
+ }
- preventEvent(event);
- removeClass(body, "wb-lock");
- use_raf && cancelAnimationFrame(raf_timer);
+ if (move_x || move_y) {
+ if (self.max) {
+ self.restore();
+ }
- if(touch){
+ use_raf ? (raf_move = true) : self.move();
+ }
- //removeListener(self.dom, "touchmove", preventEvent);
- removeListener(window, "touchmove", handler_mousemove, eventOptionsPassive);
- removeListener(window, "touchend", handler_mouseup, eventOptionsPassive);
- }
- else{
+ if (resize_w || move_x) {
+ x = pageX;
+ }
- //removeListener(this, "mouseleave", handler_mouseup);
- removeListener(window, "mousemove", handler_mousemove, eventOptionsPassive);
- removeListener(window, "mouseup", handler_mouseup, eventOptionsPassive);
- }
+ if (resize_h || move_y) {
+ y = pageY;
+ }
+ }
+
+ function handler_mouseup(event) {
+ preventEvent(event);
+ removeClass(body, "wb-lock");
+ use_raf && cancelAnimationFrame(raf_timer);
+
+ if (touch) {
+ //removeListener(self.dom, "touchmove", preventEvent);
+ removeListener(
+ window,
+ "touchmove",
+ handler_mousemove,
+ eventOptionsPassive
+ );
+ removeListener(window, "touchend", handler_mouseup, eventOptionsPassive);
+ } else {
+ //removeListener(this, "mouseleave", handler_mouseup);
+ removeListener(
+ window,
+ "mousemove",
+ handler_mousemove,
+ eventOptionsPassive
+ );
+ removeListener(window, "mouseup", handler_mouseup, eventOptionsPassive);
}
+ }
}
-function init(){
+function init() {
+ // TODO: the window height of iOS isn't determined correctly when the bottom toolbar disappears
- // TODO: the window height of iOS isn't determined correctly when the bottom toolbar disappears
+ // the bounding rect provides more precise dimensions (float values)
+ // //const rect = doc.getBoundingClientRect();
+ // this.root_w = doc.clientWidth; //rect.width || (rect.right - rect.left);
+ // this.root_h = doc.clientHeight; //rect.height || (rect.top - rect.bottom);
- // the bounding rect provides more precise dimensions (float values)
- // //const rect = doc.getBoundingClientRect();
- // this.root_w = doc.clientWidth; //rect.width || (rect.right - rect.left);
- // this.root_h = doc.clientHeight; //rect.height || (rect.top - rect.bottom);
+ // if(ios){
+ // this.root_h = window.innerHeight * (this.root_w / window.innerWidth);
+ // }
- // if(ios){
- // this.root_h = window.innerHeight * (this.root_w / window.innerWidth);
- // }
+ // root_w = doc.clientWidth;
+ // root_h = doc.clientHeight;
- // root_w = doc.clientWidth;
- // root_h = doc.clientHeight;
+ // root_w = body.clientWidth;
+ // root_h = body.clientHeight;
- // root_w = body.clientWidth;
- // root_h = body.clientHeight;
-
- const doc = document.documentElement;
- root_w = doc.clientWidth;
- root_h = doc.clientHeight;
+ const doc = document.documentElement;
+ root_w = doc.clientWidth;
+ root_h = doc.clientHeight;
}
/**
@@ -811,16 +775,15 @@ function init(){
* @this WinBox
*/
-WinBox.prototype.mount = function(src){
-
- // handles mounting over:
- this.unmount();
+WinBox.prototype.mount = function (src) {
+ // handles mounting over:
+ this.unmount();
- src._backstore || (src._backstore = src.parentNode);
- this.body.textContent = "";
- this.body.appendChild(src);
+ src._backstore || (src._backstore = src.parentNode);
+ this.body.textContent = "";
+ this.body.appendChild(src);
- return this;
+ return this;
};
/**
@@ -828,74 +791,65 @@ WinBox.prototype.mount = function(src){
* @this WinBox
*/
-WinBox.prototype.unmount = function(dest){
-
- const node = this.body.firstChild;
-
- if(node){
+WinBox.prototype.unmount = function (dest) {
+ const node = this.body.firstChild;
- const root = dest || node._backstore;
+ if (node) {
+ const root = dest || node._backstore;
- root && root.appendChild(node);
- node._backstore = dest;
- }
+ root && root.appendChild(node);
+ node._backstore = dest;
+ }
- return this;
+ return this;
};
/**
* @this WinBox
*/
-WinBox.prototype.setTitle = function(title){
-
- const node = getByClass(this.dom, "wb-title");
- setText(node, this.title = title);
- return this;
+WinBox.prototype.setTitle = function (title) {
+ const node = getByClass(this.dom, "wb-title");
+ setText(node, (this.title = title));
+ return this;
};
/**
* @this WinBox
*/
-WinBox.prototype.setIcon = function(src){
-
- const img = getByClass(this.dom, "wb-icon");
- setStyle(img, "background-image", "url(" + src + ")");
- setStyle(img, "display", "inline-block");
+WinBox.prototype.setIcon = function (src) {
+ const img = getByClass(this.dom, "wb-icon");
+ setStyle(img, "background-image", "url(" + src + ")");
+ setStyle(img, "display", "inline-block");
- return this;
+ return this;
};
/**
* @this WinBox
*/
-WinBox.prototype.setBackground = function(background){
-
- setStyle(this.dom, "background", background);
- return this;
+WinBox.prototype.setBackground = function (background) {
+ setStyle(this.dom, "background", background);
+ return this;
};
/**
* @this WinBox
*/
-WinBox.prototype.setUrl = function(url, onload){
+WinBox.prototype.setUrl = function (url, onload) {
+ const node = this.body.firstChild;
- const node = this.body.firstChild;
+ if (node && node.tagName.toLowerCase() === "iframe") {
+ node.src = url;
+ } else {
+ this.body.innerHTML = '
';
+ onload && (this.body.firstChild.onload = onload);
+ }
- if(node && (node.tagName.toLowerCase() === "iframe")){
-
- node.src = url;
- }
- else{
-
- this.body.innerHTML = '
';
- onload && (this.body.firstChild.onload = onload);
- }
-
- return this;
+ return this;
};
/**
@@ -903,41 +857,35 @@ WinBox.prototype.setUrl = function(url, onload){
* @this WinBox
*/
-WinBox.prototype.focus = function(state){
-
- if(state === false){
-
- return this.blur();
- }
-
- if(!this.focused){
-
- const stack_length = stack_win.length;
+WinBox.prototype.focus = function (state) {
+ if (state === false) {
+ return this.blur();
+ }
- if(stack_length > 1){
-
- for(let i = 1; i <= stack_length; i++){
-
- const last_focus = stack_win[stack_length - i];
+ if (!this.focused) {
+ const stack_length = stack_win.length;
- if(last_focus.focused /*&& last_focus !== this*/){
+ if (stack_length > 1) {
+ for (let i = 1; i <= stack_length; i++) {
+ const last_focus = stack_win[stack_length - i];
- last_focus.blur();
- stack_win.push(stack_win.splice(stack_win.indexOf(this), 1)[0]);
+ if (last_focus.focused /*&& last_focus !== this*/) {
+ last_focus.blur();
+ stack_win.push(stack_win.splice(stack_win.indexOf(this), 1)[0]);
- break;
- }
- }
+ break;
}
-
- setStyle(this.dom, "z-index", ++index_counter);
- this.index = index_counter;
- this.addClass("focus");
- this.focused = true;
- this.onfocus && this.onfocus();
+ }
}
- return this;
+ setStyle(this.dom, "z-index", ++index_counter);
+ this.index = index_counter;
+ this.addClass("focus");
+ this.focused = true;
+ this.onfocus && this.onfocus();
+ }
+
+ return this;
};
/**
@@ -945,21 +893,18 @@ WinBox.prototype.focus = function(state){
* @this WinBox
*/
-WinBox.prototype.blur = function(state){
+WinBox.prototype.blur = function (state) {
+ if (state === false) {
+ return this.focus();
+ }
- if(state === false){
-
- return this.focus();
- }
-
- if(this.focused){
-
- this.removeClass("focus");
- this.focused = false;
- this.onblur && this.onblur();
- }
+ if (this.focused) {
+ this.removeClass("focus");
+ this.focused = false;
+ this.onblur && this.onblur();
+ }
- return this;
+ return this;
};
/**
@@ -967,19 +912,16 @@ WinBox.prototype.blur = function(state){
* @this WinBox
*/
-WinBox.prototype.hide = function(state){
-
- if(state === false){
-
- return this.show();
- }
-
- if(!this.hidden){
+WinBox.prototype.hide = function (state) {
+ if (state === false) {
+ return this.show();
+ }
- this.onhide && this.onhide();
- this.hidden = true;
- return this.addClass("hide");
- }
+ if (!this.hidden) {
+ this.onhide && this.onhide();
+ this.hidden = true;
+ return this.addClass("hide");
+ }
};
/**
@@ -987,19 +929,16 @@ WinBox.prototype.hide = function(state){
* @this WinBox
*/
-WinBox.prototype.show = function(state){
-
- if(state === false){
-
- return this.hide();
- }
-
- if(this.hidden){
+WinBox.prototype.show = function (state) {
+ if (state === false) {
+ return this.hide();
+ }
- this.onshow && this.onshow();
- this.hidden = false;
- return this.removeClass("hide");
- }
+ if (this.hidden) {
+ this.onshow && this.onshow();
+ this.hidden = false;
+ return this.removeClass("hide");
+ }
};
/**
@@ -1007,89 +946,75 @@ WinBox.prototype.show = function(state){
* @this WinBox
*/
-WinBox.prototype.minimize = function(state){
-
- if(state === false){
+WinBox.prototype.minimize = function (state) {
+ if (state === false) {
+ return this.restore();
+ }
- return this.restore();
- }
-
- if(is_fullscreen){
+ if (is_fullscreen) {
+ cancel_fullscreen();
+ }
- cancel_fullscreen();
- }
+ if (this.max) {
+ this.removeClass("max");
+ this.max = false;
+ }
- if(this.max){
+ if (!this.min) {
+ stack_min.push(this);
+ update_min_stack();
+ this.dom.title = this.title;
+ this.addClass("min");
+ this.min = true;
- this.removeClass("max");
- this.max = false;
+ if (this.focused) {
+ this.blur();
+ focus_next();
}
- if(!this.min){
-
- stack_min.push(this);
- update_min_stack();
- this.dom.title = this.title;
- this.addClass("min");
- this.min = true;
-
- if(this.focused){
-
- this.blur();
- focus_next();
- }
-
- this.onminimize && this.onminimize();
- }
+ this.onminimize && this.onminimize();
+ }
- return this;
+ return this;
};
-function focus_next(){
-
- const stack_length = stack_win.length;
-
- if(stack_length){
-
- for(let i = stack_length - 1; i >= 0; i--){
-
- const last_focus = stack_win[i];
+function focus_next() {
+ const stack_length = stack_win.length;
- if(!last_focus.min /*&& last_focus !== this*/){
+ if (stack_length) {
+ for (let i = stack_length - 1; i >= 0; i--) {
+ const last_focus = stack_win[i];
- last_focus.focus();
- break;
- }
- }
+ if (!last_focus.min /*&& last_focus !== this*/) {
+ last_focus.focus();
+ break;
+ }
}
+ }
}
/**
* @this WinBox
*/
-WinBox.prototype.restore = function(){
-
- if(is_fullscreen){
+WinBox.prototype.restore = function () {
+ if (is_fullscreen) {
+ cancel_fullscreen();
+ }
- cancel_fullscreen();
- }
+ if (this.min) {
+ remove_min_stack(this);
+ this.resize().move();
+ this.onrestore && this.onrestore();
+ }
- if(this.min){
-
- remove_min_stack(this);
- this.resize().move();
- this.onrestore && this.onrestore();
- }
-
- if(this.max){
-
- this.max = false;
- this.removeClass("max").resize().move();
- this.onrestore && this.onrestore();
- }
+ if (this.max) {
+ this.max = false;
+ this.removeClass("max").resize().move();
+ this.onrestore && this.onrestore();
+ }
- return this;
+ return this;
};
/**
@@ -1097,43 +1022,33 @@ WinBox.prototype.restore = function(){
* @this WinBox
*/
-WinBox.prototype.maximize = function(state){
-
- if(state === false){
-
- return this.restore();
- }
-
- if(is_fullscreen){
-
- cancel_fullscreen();
- }
-
- if(this.min){
-
- remove_min_stack(this);
- }
-
- if(!this.max){
-
- this.addClass("max").resize(
-
- root_w - this.left - this.right,
- root_h - this.top - this.bottom /* - 1 */,
- true
-
- ).move(
-
- this.left,
- this.top,
- true
- );
-
- this.max = true;
- this.onmaximize && this.onmaximize();
- }
-
- return this;
+WinBox.prototype.maximize = function (state) {
+ if (state === false) {
+ return this.restore();
+ }
+
+ if (is_fullscreen) {
+ cancel_fullscreen();
+ }
+
+ if (this.min) {
+ remove_min_stack(this);
+ }
+
+ if (!this.max) {
+ this.addClass("max")
+ .resize(
+ root_w - this.left - this.right,
+ root_h - this.top - this.bottom /* - 1 */,
+ true
+ )
+ .move(this.left, this.top, true);
+
+ this.max = true;
+ this.onmaximize && this.onmaximize();
+ }
+
+ return this;
};
/**
@@ -1141,62 +1056,53 @@ WinBox.prototype.maximize = function(state){
* @this WinBox
*/
-WinBox.prototype.fullscreen = function(state){
-
- if(this.min){
+WinBox.prototype.fullscreen = function (state) {
+ if (this.min) {
+ remove_min_stack(this);
+ this.resize().move();
+ }
- remove_min_stack(this);
- this.resize().move();
- }
+ // fullscreen could be changed by user manually!
- // fullscreen could be changed by user manually!
+ if (!is_fullscreen || !cancel_fullscreen()) {
+ // requestFullscreen is executed as async and returns promise.
+ // in this case it is better to set the state to "this.full" after the requestFullscreen was fired,
+ // because it may break when browser does not support fullscreen properly and bypass it silently.
- if(!is_fullscreen || !cancel_fullscreen()){
-
- // requestFullscreen is executed as async and returns promise.
- // in this case it is better to set the state to "this.full" after the requestFullscreen was fired,
- // because it may break when browser does not support fullscreen properly and bypass it silently.
-
- this.body[prefix_request]();
- is_fullscreen = this;
- this.full = true;
- this.onfullscreen && this.onfullscreen();
- }
- else if(state === false){
-
- return this.restore();
- }
+ this.body[prefix_request]();
+ is_fullscreen = this;
+ this.full = true;
+ this.onfullscreen && this.onfullscreen();
+ } else if (state === false) {
+ return this.restore();
+ }
- return this;
+ return this;
};
-function has_fullscreen(){
-
- return (
-
- document["fullscreen"] ||
- document["fullscreenElement"] ||
- document["webkitFullscreenElement"] ||
- document["mozFullScreenElement"]
- );
+function has_fullscreen() {
+ return (
+ document["fullscreen"] ||
+ document["fullscreenElement"] ||
+ document["webkitFullscreenElement"] ||
+ document["mozFullScreenElement"]
+ );
}
/**
* @return {boolean|void}
*/
-function cancel_fullscreen(){
-
- is_fullscreen.full = false;
-
- if(has_fullscreen()){
+function cancel_fullscreen() {
+ is_fullscreen.full = false;
- // exitFullscreen is executed as async and returns promise.
- // the important part is that the promise callback runs before the event "onresize" was fired!
+ if (has_fullscreen()) {
+ // exitFullscreen is executed as async and returns promise.
+ // the important part is that the promise callback runs before the event "onresize" was fired!
- document[prefix_exit]();
- return true;
- }
+ document[prefix_exit]();
+ return true;
+ }
}
/**
@@ -1204,27 +1110,24 @@ function cancel_fullscreen(){
* @this WinBox
*/
-WinBox.prototype.close = function(force) {
-
- if(this.onclose && this.onclose(force)){
-
- return true;
- }
-
- if(this.min){
+WinBox.prototype.close = function (force) {
+ if (this.onclose && this.onclose(force)) {
+ return true;
+ }
- remove_min_stack(this);
- }
+ if (this.min) {
+ remove_min_stack(this);
+ }
- stack_win.splice(stack_win.indexOf(this), 1);
+ stack_win.splice(stack_win.indexOf(this), 1);
- this.unmount();
- this.dom.remove();
- this.dom.textContent = "";
- this.dom["winbox"] = null;
- this.body = null;
- this.dom = null;
- this.focused && focus_next();
+ this.unmount();
+ this.dom.remove();
+ this.dom.textContent = "";
+ this.dom["winbox"] = null;
+ this.body = null;
+ this.dom = null;
+ this.focused && focus_next();
};
/**
@@ -1234,25 +1137,25 @@ WinBox.prototype.close = function(force) {
* @this WinBox
*/
-WinBox.prototype.move = function(x, y, _skip_update){
-
- if(!x && (x !== 0)){
-
- x = this.x;
- y = this.y;
- }
- else if(!_skip_update){
-
- this.x = x ? x = parse(x, root_w - this.left - this.right, this.width) : 0;
- this.y = y ? y = parse(y, root_h - this.top - this.bottom, this.height) : 0;
- }
-
- //setStyle(this.dom, "transform", "translate(" + x + "px," + y + "px)");
- setStyle(this.dom, "left", x + "px");
- setStyle(this.dom, "top", y + "px");
-
- this.onmove && this.onmove(x, y);
- return this;
+WinBox.prototype.move = function (x, y, _skip_update) {
+ if (!x && x !== 0) {
+ x = this.x;
+ y = this.y;
+ } else if (!_skip_update) {
+ this.x = x
+ ? (x = parse(x, root_w - this.left - this.right, this.width))
+ : 0;
+ this.y = y
+ ? (y = parse(y, root_h - this.top - this.bottom, this.height))
+ : 0;
+ }
+
+ //setStyle(this.dom, "transform", "translate(" + x + "px," + y + "px)");
+ setStyle(this.dom, "left", x + "px");
+ setStyle(this.dom, "top", y + "px");
+
+ this.onmove && this.onmove(x, y);
+ return this;
};
/**
@@ -1262,27 +1165,27 @@ WinBox.prototype.move = function(x, y, _skip_update){
* @this WinBox
*/
-WinBox.prototype.resize = function(w, h, _skip_update){
-
- if(!w && (w !== 0)){
-
- w = this.width;
- h = this.height;
- }
- else if(!_skip_update){
-
- this.width = w ? w = parse(w, this.maxwidth /*- this.left - this.right*/) : 0;
- this.height = h ? h = parse(h, this.maxheight /*- this.top - this.bottom*/) : 0;
-
- w = Math.max(w, this.minwidth);
- h = Math.max(h, this.minheight);
- }
-
- setStyle(this.dom, "width", w + "px");
- setStyle(this.dom, "height", h + "px");
-
- this.onresize && this.onresize(w, h);
- return this;
+WinBox.prototype.resize = function (w, h, _skip_update) {
+ if (!w && w !== 0) {
+ w = this.width;
+ h = this.height;
+ } else if (!_skip_update) {
+ this.width = w
+ ? (w = parse(w, this.maxwidth /*- this.left - this.right*/))
+ : 0;
+ this.height = h
+ ? (h = parse(h, this.maxheight /*- this.top - this.bottom*/))
+ : 0;
+
+ w = Math.max(w, this.minwidth);
+ h = Math.max(h, this.minheight);
+ }
+
+ setStyle(this.dom, "width", w + "px");
+ setStyle(this.dom, "height", h + "px");
+
+ this.onresize && this.onresize(w, h);
+ return this;
};
/**
@@ -1290,23 +1193,25 @@ WinBox.prototype.resize = function(w, h, _skip_update){
* @this WinBox
*/
-WinBox.prototype.addControl = function(control){
-
- const classname = control["class"];
- const image = control.image;
- const click = control.click;
- const index = control.index;
- const node = document.createElement("span");
- const icons = getByClass(this.dom, "wb-control");
- const self = this;
-
- if(classname) node.className = classname;
- if(image) setStyle(node, "background-image", "url(" + image + ")");
- if(click) node.onclick = function(event){ click.call(this, event, self) };
-
- icons.insertBefore(node, icons.childNodes[index || 0]);
-
- return this;
+WinBox.prototype.addControl = function (control) {
+ const classname = control["class"];
+ const image = control.image;
+ const click = control.click;
+ const index = control.index;
+ const node = document.createElement("span");
+ const icons = getByClass(this.dom, "wb-control");
+ const self = this;
+
+ if (classname) node.className = classname;
+ if (image) setStyle(node, "background-image", "url(" + image + ")");
+ if (click)
+ node.onclick = function (event) {
+ click.call(this, event, self);
+ };
+
+ icons.insertBefore(node, icons.childNodes[index || 0]);
+
+ return this;
};
/**
@@ -1314,11 +1219,10 @@ WinBox.prototype.addControl = function(control){
* @this WinBox
*/
-WinBox.prototype.removeControl = function(control){
-
- control = getByClass(this.dom, control);
- control && control.remove();
- return this;
+WinBox.prototype.removeControl = function (control) {
+ control = getByClass(this.dom, control);
+ control && control.remove();
+ return this;
};
/**
@@ -1326,10 +1230,9 @@ WinBox.prototype.removeControl = function(control){
* @this WinBox
*/
-WinBox.prototype.addClass = function(classname){
-
- addClass(this.dom, classname);
- return this;
+WinBox.prototype.addClass = function (classname) {
+ addClass(this.dom, classname);
+ return this;
};
/**
@@ -1337,21 +1240,18 @@ WinBox.prototype.addClass = function(classname){
* @this WinBox
*/
-WinBox.prototype.removeClass = function(classname){
-
- removeClass(this.dom, classname);
- return this;
+WinBox.prototype.removeClass = function (classname) {
+ removeClass(this.dom, classname);
+ return this;
};
-
/**
* @param {string} classname
* @this WinBox
*/
-WinBox.prototype.hasClass = function(classname){
-
- return hasClass(this.dom, classname);
+WinBox.prototype.hasClass = function (classname) {
+ return hasClass(this.dom, classname);
};
/**
@@ -1359,16 +1259,16 @@ WinBox.prototype.hasClass = function(classname){
* @this WinBox
*/
-WinBox.prototype.toggleClass = function(classname){
-
- return this.hasClass(classname) ? this.removeClass(classname) : this.addClass(classname);
+WinBox.prototype.toggleClass = function (classname) {
+ return this.hasClass(classname)
+ ? this.removeClass(classname)
+ : this.addClass(classname);
};
-
/*
WinBox.prototype.use = function(plugin){
this.plugins.push(plugin);
return this;
};
-*/
\ No newline at end of file
+*/
diff --git a/task/build.js b/task/build.js
index fb064dd..84eb57c 100644
--- a/task/build.js
+++ b/task/build.js
@@ -1,5 +1,5 @@
-const child_process = require('child_process');
-const fs = require('fs');
+const child_process = require("child_process");
+const fs = require("fs");
console.log("Start build .....");
console.log();
@@ -37,95 +37,96 @@ const options = (function(argv){
const bundle = process.argv[2] === "--bundle";
//const extern = process.argv[2] === "--extern";
-const parameter = (function(opt){
+const parameter = (function (opt) {
+ let parameter = "";
- let parameter = '';
-
- for(let index in opt){
-
- if(opt.hasOwnProperty(index)){
-
- parameter += ' --' + index + '=' + opt[index];
- }
+ for (let index in opt) {
+ if (opt.hasOwnProperty(index)) {
+ parameter += " --" + index + "=" + opt[index];
}
+ }
- return parameter;
+ return parameter;
})({
-
- compilation_level: "ADVANCED_OPTIMIZATIONS", //"WHITESPACE"
- use_types_for_optimization: true,
- //new_type_inf: true,
- //jscomp_warning: "newCheckTypes",
- //jscomp_error: "strictCheckTypes",
- //jscomp_error: "newCheckTypesExtraChecks",
- generate_exports: true,
- export_local_property_definitions: true,
- language_in: "ECMASCRIPT6_STRICT",
- language_out: "ECMASCRIPT5_STRICT",
- process_closure_primitives: true,
- summary_detail_level: 3,
- warning_level: "VERBOSE",
- emit_use_strict: true,
-
- output_manifest: "log/manifest.log",
- //output_module_dependencies: "log/module_dependencies.log",
- property_renaming_report: "log/renaming_report.log",
- strict_mode_input: true,
- assume_function_wrapper: true,
-
- //transform_amd_modules: true,
- process_common_js_modules: true,
- module_resolution: "BROWSER",
- dependency_mode: "PRUNE_LEGACY",
- rewrite_polyfills: false,
- //js_module_root: "./",
- entry_point: "./src/js/webpack.js",
- //manage_closure_dependencies: true,
- //dependency_mode: "PRUNE_LEGACY",
-
- isolation_mode: "IIFE"
- //output_wrapper: "(function(){%output%}());"
-
- //formatting: "PRETTY_PRINT"
+ compilation_level: "ADVANCED_OPTIMIZATIONS", //"WHITESPACE"
+ use_types_for_optimization: true,
+ //new_type_inf: true,
+ //jscomp_warning: "newCheckTypes",
+ //jscomp_error: "strictCheckTypes",
+ //jscomp_error: "newCheckTypesExtraChecks",
+ generate_exports: true,
+ export_local_property_definitions: true,
+ language_in: "ECMASCRIPT6_STRICT",
+ language_out: "ECMASCRIPT5_STRICT",
+ process_closure_primitives: true,
+ summary_detail_level: 3,
+ warning_level: "VERBOSE",
+ emit_use_strict: true,
+
+ output_manifest: "log/manifest.log",
+ //output_module_dependencies: "log/module_dependencies.log",
+ property_renaming_report: "log/renaming_report.log",
+ strict_mode_input: true,
+ assume_function_wrapper: true,
+
+ //transform_amd_modules: true,
+ process_common_js_modules: true,
+ module_resolution: "BROWSER",
+ dependency_mode: "PRUNE_LEGACY",
+ rewrite_polyfills: false,
+ //js_module_root: "./",
+ entry_point: "./src/js/webpack.js",
+ //manage_closure_dependencies: true,
+ //dependency_mode: "PRUNE_LEGACY",
+
+ isolation_mode: "IIFE",
+ //output_wrapper: "(function(){%output%}());"
+
+ //formatting: "PRETTY_PRINT"
});
-exec((/^win/.test(process.platform) ?
-
- "\"node_modules/google-closure-compiler-windows/compiler.exe\""
-:
- "java -jar node_modules/google-closure-compiler-java/compiler.jar"
-
-) + parameter + (bundle ? " --js='tmp/**.js'" : "") + " --js='src/js/**.js' --js_output_file='" + (bundle ? "dist/winbox.bundle.min.js" : "dist/js/winbox.min.js") + "' && exit 0", function(){
-
- let build = fs.readFileSync((bundle ? "dist/winbox.bundle.min.js" : "dist/js/winbox.min.js"));
+exec(
+ (/^win/.test(process.platform)
+ ? '"node_modules/google-closure-compiler-windows/compiler.exe"'
+ : "java -jar node_modules/google-closure-compiler-java/compiler.jar") +
+ parameter +
+ (bundle ? " --js='tmp/**.js'" : "") +
+ " --js='src/js/**.js' --js_output_file='" +
+ (bundle ? "dist/winbox.bundle.min.js" : "dist/js/winbox.min.js") +
+ "' && exit 0",
+ function () {
+ let build = fs.readFileSync(
+ bundle ? "dist/winbox.bundle.min.js" : "dist/js/winbox.min.js"
+ );
let preserve = fs.readFileSync("src/js/winbox.js", "utf8");
const package_json = require("../package.json");
- preserve = preserve.replace("* WinBox.js", "* WinBox.js v" + package_json.version + (bundle ? " (Bundle)" : ""));
- build = preserve.substring(0, preserve.indexOf('*/') + 2) + "\n" + build;
- fs.writeFileSync((bundle ? "dist/winbox.bundle.min.js" : "dist/js/winbox.min.js"), build);
+ preserve = preserve.replace(
+ "* WinBox.js",
+ "* WinBox.js v" + package_json.version + (bundle ? " (Bundle)" : "")
+ );
+ build = preserve.substring(0, preserve.indexOf("*/") + 2) + "\n" + build;
+ fs.writeFileSync(
+ bundle ? "dist/winbox.bundle.min.js" : "dist/js/winbox.min.js",
+ build
+ );
console.log("Build Complete.");
-});
-
-function exec(prompt, callback){
-
- const child = child_process.exec(prompt, function(err, stdout, stderr){
-
- if(err){
-
- console.error(err);
- }
- else{
-
- if(callback){
-
- callback();
- }
- }
- });
+ }
+);
+
+function exec(prompt, callback) {
+ const child = child_process.exec(prompt, function (err, stdout, stderr) {
+ if (err) {
+ console.error(err);
+ } else {
+ if (callback) {
+ callback();
+ }
+ }
+ });
- child.stdout.pipe(process.stdout);
- child.stderr.pipe(process.stderr);
+ child.stdout.pipe(process.stdout);
+ child.stderr.pipe(process.stderr);
}
diff --git a/task/bundle.js b/task/bundle.js
index 260ab87..242cd9b 100644
--- a/task/bundle.js
+++ b/task/bundle.js
@@ -1,5 +1,5 @@
-const { base64Sync } = require('base64-img');
-const fs = require('fs');
+const { base64Sync } = require("base64-img");
+const fs = require("fs");
fs.existsSync("log") || fs.mkdirSync("log");
fs.existsSync("tmp") || fs.mkdirSync("tmp");
@@ -10,47 +10,46 @@ const image = process.argv[2] === "--image";
//const template = process.argv[2] === "--template";
const style = process.argv[2] === "--style";
-(function(){
-
- if(image){
-
- // TODO provide custom filenames
-
- const compressed = {
-
- max: base64Sync('dist/img/max.svg'),
- close: base64Sync('dist/img/close.svg'),
- full: base64Sync('dist/img/full.svg'),
- //restore: base64Sync('dist/img/restore.svg'),
- //exit: base64Sync('dist/img/exit.svg'),
- min: base64Sync('dist/img/min.svg')
- };
-
- let tmp = "";
-
- for(let key in compressed){
-
- if(compressed.hasOwnProperty(key)){
-
- tmp += ("@" + key + ": \"" + compressed[key] + "\";\n");
- }
- }
-
- fs.writeFileSync("tmp/images.less", tmp);
- fs.writeFileSync("tmp/bundle.less", '@import "../src/css/winbox.less"; @import "images.less";'); // @import "../src/css/themes/modern.less"; @import "../src/css/themes/white.less";
- }
-
- // ----------------------
-
- if(style){
-
- fs.writeFileSync("tmp/style.js",
-
- 'const style = document.createElement("style");' +
- 'style.innerHTML = "' + fs.readFileSync("dist/css/winbox.min.css", "utf8").replace(/"/g, "'") + '";' +
- 'const head = document.getElementsByTagName("head")[0];' +
- 'if(head.firstChild) head.insertBefore(style, head.firstChild); else head.appendChild(style);'
- );
+(function () {
+ if (image) {
+ // TODO provide custom filenames
+
+ const compressed = {
+ max: base64Sync("dist/img/max.svg"),
+ close: base64Sync("dist/img/close.svg"),
+ full: base64Sync("dist/img/full.svg"),
+ //restore: base64Sync('dist/img/restore.svg'),
+ //exit: base64Sync('dist/img/exit.svg'),
+ min: base64Sync("dist/img/min.svg"),
+ };
+
+ let tmp = "";
+
+ for (let key in compressed) {
+ if (compressed.hasOwnProperty(key)) {
+ tmp += "@" + key + ': "' + compressed[key] + '";\n';
+ }
}
+ fs.writeFileSync("tmp/images.less", tmp);
+ fs.writeFileSync(
+ "tmp/bundle.less",
+ '@import "../src/css/winbox.less"; @import "images.less";'
+ ); // @import "../src/css/themes/modern.less"; @import "../src/css/themes/white.less";
+ }
+
+ // ----------------------
+
+ if (style) {
+ fs.writeFileSync(
+ "tmp/style.js",
+
+ 'const style = document.createElement("style");' +
+ 'style.innerHTML = "' +
+ fs.readFileSync("dist/css/winbox.min.css", "utf8").replace(/"/g, "'") +
+ '";' +
+ 'const head = document.getElementsByTagName("head")[0];' +
+ "if(head.firstChild) head.insertBefore(style, head.firstChild); else head.appendChild(style);"
+ );
+ }
})();
diff --git a/task/clean.js b/task/clean.js
index 46d7a68..5408791 100644
--- a/task/clean.js
+++ b/task/clean.js
@@ -1,26 +1,26 @@
const fs = require("fs");
const path = require("path");
-const removeDir = function(path) {
- if (fs.existsSync(path)) {
- const files = fs.readdirSync(path);
+const removeDir = function (path) {
+ if (fs.existsSync(path)) {
+ const files = fs.readdirSync(path);
- if (files.length > 0) {
- files.forEach(function(filename) {
- if (fs.statSync(path + "/" + filename).isDirectory()) {
- removeDir(path + "/" + filename);
- } else {
- fs.unlinkSync(path + "/" + filename);
- }
- });
-
- fs.rmdirSync(path);
+ if (files.length > 0) {
+ files.forEach(function (filename) {
+ if (fs.statSync(path + "/" + filename).isDirectory()) {
+ removeDir(path + "/" + filename);
} else {
- fs.rmdirSync(path);
+ fs.unlinkSync(path + "/" + filename);
}
+ });
+
+ fs.rmdirSync(path);
+ } else {
+ fs.rmdirSync(path);
}
-}
+ }
+};
-const distPath = path.join('dist')
+const distPath = path.join("dist");
removeDir(distPath);
diff --git a/task/server.js b/task/server.js
index 7c9ce01..503f5e8 100644
--- a/task/server.js
+++ b/task/server.js
@@ -2,51 +2,46 @@
var port = process.argv[2];
-if(!port){
-
- if(/^win/.test(process.platform)){
-
- port = 80;
- }
- else{
-
- port = 8080;
- }
+if (!port) {
+ if (/^win/.test(process.platform)) {
+ port = 80;
+ } else {
+ port = 8080;
+ }
}
-var ws = require('web-servo');
+var ws = require("web-servo");
ws.config({
-
- "server": {
- "port": port,
- "dir": "/",
- "exitOnError": false,
- "ssl": {
- "enabled": false,
- "key": "",
- "cert": ""
- }
- },
- "page": {
- "default": "index.html"
+ server: {
+ port: port,
+ dir: "/",
+ exitOnError: false,
+ ssl: {
+ enabled: false,
+ key: "",
+ cert: "",
},
- "methods": {
- "allowed": [
- "OPTIONS",
- "GET",
- "POST",
- "HEAD",
- "PUT",
- "PATCH",
- "DELETE"
- //"COPY",
- //"LINK",
- //"UNLINK",
- //"TRACE",
- //"CONNECT"
- ]
- }
+ },
+ page: {
+ default: "index.html",
+ },
+ methods: {
+ allowed: [
+ "OPTIONS",
+ "GET",
+ "POST",
+ "HEAD",
+ "PUT",
+ "PATCH",
+ "DELETE",
+ //"COPY",
+ //"LINK",
+ //"UNLINK",
+ //"TRACE",
+ //"CONNECT"
+ ],
+ },
});
//ws.setConfigVar('server.port', port);
diff --git a/task/svgo.js b/task/svgo.js
index db366af..a0c1a41 100644
--- a/task/svgo.js
+++ b/task/svgo.js
@@ -1,59 +1,56 @@
-const fs = require('fs');
-const path = require('path');
-let { optimize } = require('svgo');
+const fs = require("fs");
+const path = require("path");
+let { optimize } = require("svgo");
const plugins = [
- 'cleanupAttrs',
- 'removeDoctype',
- 'removeXMLProcInst',
- 'removeComments',
- 'removeMetadata',
- 'removeTitle',
- 'removeDesc',
- 'removeUselessDefs',
- 'removeEditorsNSData',
- 'removeEmptyAttrs',
- 'removeHiddenElems',
- 'removeEmptyText',
- 'removeEmptyContainers',
- // 'removeViewBox',
- 'cleanupEnableBackground',
- 'convertStyleToAttrs',
- 'convertColors',
- 'convertPathData',
- 'convertTransform',
- 'removeUnknownsAndDefaults',
- 'removeNonInheritableGroupAttrs',
- 'removeUselessStrokeAndFill',
- 'removeUnusedNS',
- 'cleanupIDs',
- 'cleanupNumericValues',
- 'moveElemsAttrsToGroup',
- 'moveGroupAttrsToElems',
- 'collapseGroups',
- // 'removeRasterImages',
- 'mergePaths',
- 'convertShapeToPath',
- 'sortAttrs',
- 'removeDimensions',
- //{ name: 'removeAttrs', params: { attrs: '(stroke|fill)' } },
+ "cleanupAttrs",
+ "removeDoctype",
+ "removeXMLProcInst",
+ "removeComments",
+ "removeMetadata",
+ "removeTitle",
+ "removeDesc",
+ "removeUselessDefs",
+ "removeEditorsNSData",
+ "removeEmptyAttrs",
+ "removeHiddenElems",
+ "removeEmptyText",
+ "removeEmptyContainers",
+ // 'removeViewBox',
+ "cleanupEnableBackground",
+ "convertStyleToAttrs",
+ "convertColors",
+ "convertPathData",
+ "convertTransform",
+ "removeUnknownsAndDefaults",
+ "removeNonInheritableGroupAttrs",
+ "removeUselessStrokeAndFill",
+ "removeUnusedNS",
+ "cleanupIDs",
+ "cleanupNumericValues",
+ "moveElemsAttrsToGroup",
+ "moveGroupAttrsToElems",
+ "collapseGroups",
+ // 'removeRasterImages',
+ "mergePaths",
+ "convertShapeToPath",
+ "sortAttrs",
+ "removeDimensions",
+ //{ name: 'removeAttrs', params: { attrs: '(stroke|fill)' } },
];
-
-const directoryPath = 'dist/img';
+const directoryPath = "dist/img";
const files = fs.readdirSync(directoryPath);
-files.forEach(function(filepath){
-
- if(filepath.endsWith(".svg")){
-
- filepath = path.resolve(__dirname, "..", directoryPath, filepath);
+files.forEach(function (filepath) {
+ if (filepath.endsWith(".svg")) {
+ filepath = path.resolve(__dirname, "..", directoryPath, filepath);
- console.log(filepath);
+ console.log(filepath);
- const data = fs.readFileSync(filepath, 'utf8');
- const result = optimize(data, { path: filepath, plugins: plugins });
+ const data = fs.readFileSync(filepath, "utf8");
+ const result = optimize(data, { path: filepath, plugins: plugins });
- fs.writeFileSync(filepath, result.data);
- }
+ fs.writeFileSync(filepath, result.data);
+ }
});