Add IMAP webmail tag, admin/opensource subpage tiers, store/cart, htmleditor, uploads
New __imap*/__smtpsend/__eval Jet tags give templates real IMAP (list/message/flag/delete/move/search/folders/accounts) and SMTP-send capability, backing the new /email webmail client (email.jet/ email.menu, assets/images/email.js + newemail.js) and its mainpagetemplate.jet-based page shell. Most of this tag family's source was already being built into the live site (Tag.cpp already registered __imap/__imaplist/__imapmessage/__imapflag/__imapdelete/ __eval) but had never actually been committed; this also registers and commits the remaining five (__imapmove/__imapfolders/ __imapsearch/__smtpsend/__imapaccounts). admin.page/admin.menu gain a real subpage tier (admin-email, admin-newemail, admin-invoices, admin-products, admin-users) replacing several previously top-level pages, mirrored by a similar opensource.page subpage tier (opensource-overview/asm1802/barantmail/ jet/serverframework/synthmax) - old top-level pages retired via git rename (asm1802.page, jet.page, serverframework.page, admin_invoices.page); barantmail.page is dropped outright, folded into opensource-barantmail.subpage. New storefront (store.page, store-createstore.subpage, barantstore.page) and cart flow (cart.jet, updatecartqty.proc, removecartitem.proc, editproduct.page/selectproduct.proc/ update_product.proc for inventory maintenance against the barant database). New document upload/download manager (documents.jet, documents_api.jet, documents_upload.proc, documents_delete.proc, assets/images/documents.js + documents-page.js) with a persistent floating panel, and a rich-text page editor (htmleditor.jet/.page, createhtmleditor.proc, savehtmleditor.proc, assets/images/htmleditor.js + its icon/logo assets). SESSIONCTL.tag: login now redirects back to the originally-requested page instead of always landing on /account ($[start:0] vs $[start] variable-name mismatch). main.css/menu.bar/invoices.menu/jet_overview.section/login.menu: styling and navigation updates for the above; new site assets (fonts, images, audio) referenced by them. jetc/build-assets.sh, list_jet_files.sh, lowercase_jet.py, strip_fragments.py: small dev tooling used while building the above.
This commit is contained in:
1 parent
b0cadc3f08
commit
c1491b044b
115 files changed
+6174
-137
No files matched your search
@@ -0,0 +1,678 @@
|
||||
function b64encode(str) {
|
||||
return btoa(unescape(encodeURIComponent(str)));
|
||||
}
|
||||
function submitNewLetter(form) {
|
||||
var name = document.getElementById('filename_display').value;
|
||||
if (!/^[A-Za-z0-9_-]+$/.test(name)) {
|
||||
alert('File name may only contain letters, numbers, underscores and hyphens.');
|
||||
return false;
|
||||
}
|
||||
form.filename.value = name;
|
||||
return true;
|
||||
}
|
||||
|
||||
var mainpage;
|
||||
var control;
|
||||
var result;
|
||||
var mousedownx;
|
||||
var mousedowny;
|
||||
var dragHint = "move";
|
||||
var data;
|
||||
var showGrid = false;
|
||||
var snapToGrid = false;
|
||||
var gridSize = 10;
|
||||
var selected;
|
||||
var firstSelected;
|
||||
var itemparameters;
|
||||
var grid;
|
||||
var context;
|
||||
var draggingHTML;
|
||||
var window_dragging = false;
|
||||
const undo = [];
|
||||
var undoIndex = 0;
|
||||
var lastRedo;
|
||||
var mode = 'MOUSEUP';
|
||||
var textobj;
|
||||
var lastdragover;
|
||||
var pendingDragover;
|
||||
var dropIndicator;
|
||||
var sequence = 0;
|
||||
|
||||
function showDropIndicator(target) {
|
||||
if(!dropIndicator) {
|
||||
dropIndicator = document.createElement('div');
|
||||
dropIndicator.style.position = 'fixed';
|
||||
dropIndicator.style.height = '4px';
|
||||
dropIndicator.style.background = '#0088ff';
|
||||
dropIndicator.style.zIndex = '99999';
|
||||
dropIndicator.style.pointerEvents = 'none';
|
||||
document.body.appendChild(dropIndicator);
|
||||
}
|
||||
let rect = target.getBoundingClientRect();
|
||||
dropIndicator.style.left = rect.left + 'px';
|
||||
dropIndicator.style.width = rect.width + 'px';
|
||||
dropIndicator.style.top = (rect.top - 2) + 'px';
|
||||
dropIndicator.style.display = 'block';
|
||||
}
|
||||
|
||||
function hideDropIndicator() {
|
||||
if(dropIndicator) {
|
||||
dropIndicator.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function saveUndo() {
|
||||
undo[undoIndex++] = mainpage.innerHTML;
|
||||
}
|
||||
|
||||
function do_undo() {
|
||||
if(undoIndex > 0) {
|
||||
mainpage.innerHTML = undo[--undoIndex];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function do_redo() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function init() {
|
||||
mainpage = document.getElementById("mainpage");
|
||||
data = document.getElementById("data");
|
||||
itemparameters = document.getElementById("itemparameters");
|
||||
var gridsize = document.getElementById("gridsize");
|
||||
gridsize.value = gridSize;
|
||||
grid = document.getElementById("grid");
|
||||
context = grid.getContext("2d");
|
||||
drawGrid();
|
||||
buildToolbar();
|
||||
document.designMode = 'off';
|
||||
}
|
||||
|
||||
function getLayerMap(element) {
|
||||
var map = '';
|
||||
if(element.id != 'mainpage') {
|
||||
var curelem = element;
|
||||
while(curelem.id != 'mainpage') {
|
||||
map = '<' + curelem.nodeName + '>' + map;
|
||||
curelem = curelem.parentNode;
|
||||
}
|
||||
}
|
||||
document.getElementById('map').innerHTML = map;
|
||||
}
|
||||
|
||||
function jetEscape(text) {
|
||||
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
|
||||
function buildToolbar() {
|
||||
|
||||
let tbitems = [
|
||||
{
|
||||
"label": "<div>",
|
||||
"html": "<div id=\"newitem\" contenteditable=\"false\" style=\"width: 300px; height: 200px; background-color: #789;\"></div>"
|
||||
},
|
||||
{
|
||||
"label": "<input>",
|
||||
"html": "<input id=\"newitem\" type=\"text\">"
|
||||
},
|
||||
{
|
||||
"label": "<button>",
|
||||
"html": "<button id=\"newitem\" type=\"button\">Label</button>"
|
||||
},
|
||||
{
|
||||
"label": "<password>",
|
||||
"html": "<input id=\"newitem\" type=\"password\">"
|
||||
},
|
||||
{
|
||||
"label": "<checkbox>",
|
||||
"html": "<input id=\"newitem\" type=\"checkbox\">"
|
||||
},
|
||||
{
|
||||
"label": "<label>",
|
||||
"html": "<label style=\"color: #000f;\" id=\"newitem\">Label text</label>"
|
||||
},
|
||||
{
|
||||
"label": "<p>",
|
||||
"html": "<p style=\"color: #000f;\" id=\"newitem\">Type Here</p>"
|
||||
},
|
||||
{
|
||||
"label": "<hr>",
|
||||
"html": "<hr id=\"newitem\">"
|
||||
},
|
||||
{
|
||||
"label": "Jet: " + "$" + "[var]",
|
||||
"html": "<code id=\"newitem\" contenteditable=\"true\" style=\"display:inline-block; background:#eef; border:1px dashed #99c; padding:4px; font-family:monospace; white-space:pre;\">" + jetEscape("$" + "[varname]") + "</code>"
|
||||
},
|
||||
{
|
||||
"label": "Jet: <set>",
|
||||
"html": "<code id=\"newitem\" contenteditable=\"true\" style=\"display:inline-block; background:#eef; border:1px dashed #99c; padding:4px; font-family:monospace; white-space:pre;\">" + jetEscape("<set name=\"varname\" value=\"\">") + "</code>"
|
||||
},
|
||||
{
|
||||
"label": "Jet: <if>",
|
||||
"html": "<code id=\"newitem\" contenteditable=\"true\" style=\"display:inline-block; background:#eef; border:1px dashed #99c; padding:4px; font-family:monospace; white-space:pre-wrap;\">" + jetEscape("<if value1=\"" + "$" + "[varname]\" value2=\"\" type=\"eq\">\ncontent\n</if>") + "</code>"
|
||||
}
|
||||
];
|
||||
|
||||
tbitems.forEach(doit);
|
||||
function doit(currentValue, index) {
|
||||
let index2 = index + 1;
|
||||
let toolbar = document.getElementById('toolbar');
|
||||
var itemHTML = '<button type="button" id="button' + index2;
|
||||
itemHTML += '" style="width: 100%; height: 40px; border: 2px solid green;"';
|
||||
itemHTML += '>' + currentValue.label + '</button>';
|
||||
toolbar.insertAdjacentHTML("beforeend", itemHTML);
|
||||
let id = 'button' + index2;
|
||||
let button = document.getElementById(id);
|
||||
button.html = currentValue.html;
|
||||
button.addEventListener("mousedown",
|
||||
(e) => {
|
||||
e.preventDefault();
|
||||
saveUndo();
|
||||
draggingHTML = currentValue.html;
|
||||
mainpage.insertAdjacentHTML('beforeend', draggingHTML);
|
||||
let newEl = mainpage.lastElementChild;
|
||||
newEl.style.position = 'absolute';
|
||||
newEl.style.zIndex = '10000';
|
||||
newEl.style.left = '0px';
|
||||
newEl.style.top = '0px';
|
||||
startNewItemDrag(newEl);
|
||||
}
|
||||
, false);
|
||||
}
|
||||
}
|
||||
|
||||
function startNewItemDrag(el) {
|
||||
let rect = mainpage.getBoundingClientRect();
|
||||
function ndMove(e) {
|
||||
el.style.left = (e.clientX - rect.left - el.offsetWidth / 2) + 'px';
|
||||
el.style.top = (e.clientY - rect.top - el.offsetHeight / 2) + 'px';
|
||||
}
|
||||
function ndUp(e) {
|
||||
document.removeEventListener('mousemove', ndMove);
|
||||
document.removeEventListener('mouseup', ndUp);
|
||||
draggingHTML = null;
|
||||
if((typeof selected !== 'undefined') && selected) {
|
||||
selected.style.outline = '';
|
||||
}
|
||||
selected = el;
|
||||
selected.style.outline = '2px solid #0088ff';
|
||||
getLayerMap(selected);
|
||||
displayParameters();
|
||||
mode = "MOUSEUP";
|
||||
}
|
||||
document.addEventListener('mousemove', ndMove);
|
||||
document.addEventListener('mouseup', ndUp);
|
||||
}
|
||||
|
||||
function window_mousedown(win, e) {
|
||||
mousedownx = e.offsetX;
|
||||
mousedowny = e.offsetY;
|
||||
if(e.offsetX >= (win.clientWidth - 3)) {
|
||||
win.style.cursor = 'ew-resize';
|
||||
window_dragging = true;
|
||||
}
|
||||
else {
|
||||
win.style.cursor = 'default';
|
||||
window_dragging = false;
|
||||
}
|
||||
}
|
||||
|
||||
function window_mousemove(win, e) {
|
||||
}
|
||||
|
||||
function window_mouseup(win, e) {
|
||||
}
|
||||
|
||||
function drawGrid() {
|
||||
if(showGrid == true) {
|
||||
context.clearRect(0,0,grid.width,grid.height);
|
||||
context.lineWidth = 0.5;
|
||||
context.strokeStyle = "#808080";
|
||||
for(var ix = 0; ix < grid.width; ix += gridSize) {
|
||||
context.beginPath();
|
||||
context.moveTo(ix, 0);
|
||||
context.lineTo(ix, grid.height);
|
||||
context.stroke();
|
||||
context.beginPath();
|
||||
context.moveTo(0, ix);
|
||||
context.lineTo(grid.width, ix);
|
||||
context.stroke();
|
||||
}
|
||||
} else {
|
||||
context.clearRect(0,0,grid.width,grid.height);
|
||||
}
|
||||
}
|
||||
|
||||
function resetDragHint(e) {
|
||||
if(!selected) {
|
||||
return;
|
||||
}
|
||||
if(selected.style.position == 'absolute') {
|
||||
if((e.offsetX >= (parseFloat(selected.style.width) - 10)) && (e.offsetY >= (parseFloat(selected.style.height) - 10))) {
|
||||
selected.style.cursor = "nwse-resize";
|
||||
dragHint = "rightbottomresize";
|
||||
} else if((e.offsetY < 10) && (e.offsetX >= (parseFloat(selected.style.width) - 10))) {
|
||||
selected.style.cursor = "nesw-resize";
|
||||
dragHint = "righttopresize";
|
||||
} else if((e.offsetX <= 10) && (e.offsetY >= (parseFloat(selected.style.height) - 10))) {
|
||||
selected.style.cursor = "nesw-resize";
|
||||
dragHint = "leftbottomresize";
|
||||
} else if((e.offsetX <= 10) && (e.offsetY <= 10)) {
|
||||
selected.style.cursor = "nwse-resize";
|
||||
dragHint = "lefttopresize";
|
||||
} else if(e.offsetX >= (parseFloat(selected.style.width) - 10)) {
|
||||
selected.style.cursor = "ew-resize";
|
||||
dragHint = "rightresize";
|
||||
} else if(e.offsetY >= (parseFloat(selected.style.height) - 10)) {
|
||||
selected.style.cursor = "ns-resize";
|
||||
dragHint = "bottomresize";
|
||||
} else if(e.offsetX <= 10) {
|
||||
selected.style.cursor = "ew-resize";
|
||||
dragHint = "leftresize";
|
||||
} else if(e.offsetY <= 10) {
|
||||
selected.style.cursor = "ns-resize";
|
||||
dragHint = "topresize";
|
||||
} else {
|
||||
selected.style.cursor = "move";
|
||||
dragHint = "move";
|
||||
}
|
||||
} else {
|
||||
if((e.offsetX >= (parseFloat(selected.style.width) - 10)) && (e.offsetY >= (parseFloat(selected.style.height) - 10))) {
|
||||
selected.style.cursor = "nwse-resize";
|
||||
dragHint = "rightbottomresize";
|
||||
} else if(e.offsetX >= (parseFloat(selected.style.width) - 10)) {
|
||||
selected.style.cursor = "ew-resize";
|
||||
dragHint = "rightresize";
|
||||
} else if(e.offsetY >= (parseFloat(selected.style.height) - 10)) {
|
||||
selected.style.cursor = "ns-resize";
|
||||
dragHint = "bottomresize";
|
||||
} else {
|
||||
selected.style.cursor = "move";
|
||||
dragHint = "move";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mousedown(e) {
|
||||
let mouseabove = document.elementFromPoint(e.clientX, e.clientY);
|
||||
if((typeof selected === 'undefined') || (selected != mouseabove)) {
|
||||
mode = 'NEWSELECTION';
|
||||
if((typeof selected !== 'undefined') && (selected.nodeName == "DIV")) {
|
||||
document.designMode = 'off';
|
||||
selected.contentEditable = false;
|
||||
selected.blur();
|
||||
selected.style.userSelect = 'none';
|
||||
}
|
||||
if((typeof selected !== 'undefined') && selected) {
|
||||
selected.style.outline = '';
|
||||
}
|
||||
selected = mouseabove;
|
||||
selected.style.outline = '2px solid #0088ff';
|
||||
getLayerMap(selected);
|
||||
} else {
|
||||
if(mode != "TEXT") {
|
||||
mode = "DOWNONSELECTED";
|
||||
}
|
||||
}
|
||||
|
||||
if(mode != 'TEXT') {
|
||||
resetDragHint(e);
|
||||
}
|
||||
mousedownx = e.clientX;
|
||||
mousedowny = e.clientY;
|
||||
|
||||
displayParameters();
|
||||
return true;
|
||||
}
|
||||
|
||||
function mouseup(e) {
|
||||
if(mode == "TEXT") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(mode == "DOWNONSELECTED") {
|
||||
if((selected.nodeName == "DIV") || (selected.nodeName == "CODE")) {
|
||||
document.designMode = 'on';
|
||||
selected.style.userSelect = 'auto';
|
||||
selected.contentEditable = true;
|
||||
selected.style.cursor = 'text';
|
||||
selected.focus();
|
||||
mode = "TEXT";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(draggingHTML) {
|
||||
draggingHTML = null;
|
||||
}
|
||||
|
||||
if(selected && (mode == 'MOVED') && (selected.style.position == 'absolute')) {
|
||||
selected.style.pointerEvents = 'none';
|
||||
let dragover = document.elementFromPoint(e.clientX, e.clientY);
|
||||
selected.style.pointerEvents = 'auto';
|
||||
if(dragover.nodeName == 'DIV') {
|
||||
if(dragover.id != selected.parentElement.id) {
|
||||
dragover.appendChild(selected);
|
||||
selected.style.left = ((selected.getBoundingClientRect().x + e.offsetX - mousedownx) - dragover.getBoundingClientRect().x) + 'px';
|
||||
selected.style.top = ((selected.getBoundingClientRect().y + e.offsetY - mousedowny) - dragover.getBoundingClientRect().y) + 'px';
|
||||
}
|
||||
}
|
||||
} else if(selected && (mode == 'MOVED') && pendingDragover) {
|
||||
pendingDragover.prepend(selected);
|
||||
selected.style.left = parseFloat(pendingDragover.style.left) + "px";
|
||||
selected.style.top = parseFloat(pendingDragover.style.top) + "px";
|
||||
}
|
||||
pendingDragover = null;
|
||||
hideDropIndicator();
|
||||
|
||||
mode = "MOUSEUP";
|
||||
return true;
|
||||
}
|
||||
|
||||
function mousemove(e) {
|
||||
if(mode == "MOUSEUP") {
|
||||
resetDragHint(e);
|
||||
} else {
|
||||
if(mode == "TEXT") {
|
||||
return true;
|
||||
}
|
||||
|
||||
if((selected.style.position == 'static') ||
|
||||
(typeof selected.style.position === 'undefined') ||
|
||||
(selected.style.position == '')) {
|
||||
|
||||
if(dragHint == "move") {
|
||||
if(mode != "MOVED") {
|
||||
mode = "MOVED";
|
||||
}
|
||||
selected.style.pointerEvents = 'none';
|
||||
let dragover = document.elementFromPoint(e.clientX, e.clientY);
|
||||
selected.style.pointerEvents = 'auto';
|
||||
if(dragover.nodeName == 'DIV') {
|
||||
pendingDragover = dragover;
|
||||
showDropIndicator(dragover);
|
||||
}
|
||||
return true;
|
||||
} else if(dragHint == "rightbottomresize") {
|
||||
if(mode != "RESIZED") {
|
||||
saveUndo();
|
||||
mode = "RESIZED";
|
||||
}
|
||||
selected.style.width = (parseFloat(selected.style.width) + e.movementX) + "px";
|
||||
selected.style.height = (parseFloat(selected.style.height) + e.movementY) + "px";
|
||||
} else if(dragHint == "rightresize") {
|
||||
if(mode != "RESIZED") {
|
||||
saveUndo();
|
||||
mode = "RESIZED";
|
||||
}
|
||||
selected.style.width = (parseFloat(selected.style.width) + e.movementX) + "px";
|
||||
} else if(dragHint == "bottomresize") {
|
||||
if(mode != "RESIZED") {
|
||||
saveUndo();
|
||||
mode = "RESIZED";
|
||||
}
|
||||
selected.style.height = (parseFloat(selected.style.height) + e.movementY) + "px";
|
||||
}
|
||||
} else if(selected.style.position == 'absolute') {
|
||||
if(dragHint == "move") {
|
||||
if(mode != "MOVED") {
|
||||
saveUndo();
|
||||
mode = "MOVED";
|
||||
}
|
||||
selected.style.left = (parseFloat(selected.style.left) + e.movementX) + "px";
|
||||
selected.style.top = (parseFloat(selected.style.top) + e.movementY) + "px";
|
||||
} else if(dragHint == "rightbottomresize") {
|
||||
if(mode != "RESIZED") {
|
||||
saveUndo();
|
||||
mode = "RESIZED";
|
||||
}
|
||||
selected.style.width = (parseFloat(selected.style.width) + e.movementX) + "px";
|
||||
selected.style.height = (parseFloat(selected.style.height) + e.movementY) + "px";
|
||||
} else if(dragHint == "lefttopresize") {
|
||||
if(mode != "RESIZED") {
|
||||
saveUndo();
|
||||
mode = "RESIZED";
|
||||
}
|
||||
selected.style.left = (parseFloat(selected.style.left) + e.movementX) + "px";
|
||||
selected.style.top = (parseFloat(selected.style.top) + e.movementY) + "px";
|
||||
selected.style.width = (parseFloat(selected.style.width) - e.movementX) + "px";
|
||||
selected.style.height = (parseFloat(selected.style.height) - e.movementY) + "px";
|
||||
} else if(dragHint == "leftbottomresize") {
|
||||
if(mode != "RESIZED") {
|
||||
saveUndo();
|
||||
mode = "RESIZED";
|
||||
}
|
||||
selected.style.left = (parseFloat(selected.style.left) + e.movementX) + "px";
|
||||
selected.style.width = (parseFloat(selected.style.width) - e.movementX) + "px";
|
||||
selected.style.height = (parseFloat(selected.style.height) + e.movementY) + "px";
|
||||
} else if(dragHint == "righttopresize") {
|
||||
if(mode != "RESIZED") {
|
||||
saveUndo();
|
||||
mode = "RESIZED";
|
||||
}
|
||||
selected.style.top = (parseFloat(selected.style.top) + e.movementY) + "px";
|
||||
selected.style.height = (parseFloat(selected.style.height) - e.movementY) + "px";
|
||||
selected.style.width = (parseFloat(selected.style.width) + e.movementX) + "px";
|
||||
} else if(dragHint == "rightresize") {
|
||||
if(mode != "RESIZED") {
|
||||
saveUndo();
|
||||
mode = "RESIZED";
|
||||
}
|
||||
selected.style.width = (parseFloat(selected.style.width) + e.movementX) + "px";
|
||||
} else if(dragHint == "bottomresize") {
|
||||
if(mode != "RESIZED") {
|
||||
saveUndo();
|
||||
mode = "RESIZED";
|
||||
}
|
||||
selected.style.height = (parseFloat(selected.style.height) + e.movementY) + "px";
|
||||
} else if(dragHint == "leftresize") {
|
||||
if(mode != "RESIZED") {
|
||||
saveUndo();
|
||||
mode = "RESIZED";
|
||||
}
|
||||
selected.style.left = (parseFloat(selected.style.left) + e.movementX) + "px";
|
||||
selected.style.width = (parseFloat(selected.style.width) - e.movementX) + "px";
|
||||
} else if(dragHint == "topresize") {
|
||||
if(mode != "RESIZED") {
|
||||
saveUndo();
|
||||
mode = "RESIZED";
|
||||
}
|
||||
selected.style.top = (parseFloat(selected.style.top) + e.movementY) + "px";
|
||||
selected.style.height = (parseFloat(selected.style.height) - e.movementY) + "px";
|
||||
}
|
||||
displayParameters();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function heading(name) {
|
||||
let properties = document.getElementById('properties');
|
||||
properties.insertAdjacentHTML('beforeend', "<tr><td colspan=\"2\" style=\"background-color: #abc; padding: 4px; font-weight: bold;\">" + name + ":</td></tr>");
|
||||
}
|
||||
|
||||
function setColorProperty(event) {
|
||||
selected.style.setProperty(event.target.id, document.getElementById(event.target.id).value);
|
||||
}
|
||||
|
||||
function getColorProperty(cssprop) {
|
||||
let value = selected.style.getPropertyValue(cssprop);
|
||||
if(value.substring(0, 4) == "rgb(") {
|
||||
document.getElementById(cssprop).value = value;
|
||||
}
|
||||
else {
|
||||
selected.style.removeProperty(cssprop);
|
||||
}
|
||||
}
|
||||
|
||||
function setSizeProperty(event) {
|
||||
var value = document.getElementById(event.target.id);
|
||||
var units = document.getElementById(event.target.id + "Units");
|
||||
if(value.value == "") {
|
||||
units.value = "";
|
||||
} else if(units && units.value == "") {
|
||||
units.value = "px";
|
||||
}
|
||||
if(units) {
|
||||
selected.style.setProperty(event.target.id, value.value + units.value);
|
||||
}
|
||||
}
|
||||
|
||||
function getSizeProperty(cssprop) {
|
||||
let size = selected.style.getPropertyValue(cssprop);
|
||||
if(size) {
|
||||
document.getElementById(cssprop).value = parseInt(size);
|
||||
document.getElementById(cssprop + "Units").value = size.replace(/[0-9]/g, '');
|
||||
}
|
||||
}
|
||||
|
||||
function property(name, payload, cssprop, initfun, changefun) {
|
||||
let properties = document.getElementById('properties');
|
||||
properties.insertAdjacentHTML('beforeend', "<tr><td style=\"background-color: #cdf; padding: 3px 4px; vertical-align: middle; white-space: nowrap;\">" + name + ":</td><td style=\"background-color: #cdf; padding: 3px 4px; vertical-align: middle;\">" + payload + "</td></tr>");
|
||||
if(initfun) {
|
||||
initfun(cssprop);
|
||||
}
|
||||
if(cssprop) {
|
||||
document.getElementById(cssprop).addEventListener('input', changefun);
|
||||
let prop = document.getElementById(cssprop + "Units");
|
||||
if(prop) {
|
||||
prop.addEventListener('change', changefun);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function propsize(title, cssprop) {
|
||||
property(title,
|
||||
"<div style=\"display: flex; align-items: center; gap: 4px;\">" +
|
||||
"<input type=\"number\" id=\"" + cssprop + "\" style=\"flex: 1 1 auto; min-width: 0; box-sizing: border-box;\">" +
|
||||
"<select id=\"" + cssprop + "Units\" style=\"flex: 0 0 auto;\">" +
|
||||
" <option value=\"\"></option>" +
|
||||
" <option value=\"px\">px</option>" +
|
||||
" <option value=\"%\">%</option>" +
|
||||
"</select></div>",
|
||||
cssprop,
|
||||
getSizeProperty,
|
||||
setSizeProperty);
|
||||
}
|
||||
|
||||
function propcolor(title, cssprop) {
|
||||
property(title,
|
||||
"<input type=\"color\" id=\"" + cssprop + "\" style=\"height: 18px; width: 50px; margin: 0px; padding: 0px; border: none; width:85%;\">",
|
||||
cssprop,
|
||||
getColorProperty,
|
||||
setColorProperty);
|
||||
}
|
||||
|
||||
function displayParameters() {
|
||||
|
||||
if(!selected) {
|
||||
itemparameters.innerHTML = "";
|
||||
return;
|
||||
}
|
||||
|
||||
itemparameters.innerHTML = "<div style=\"width: 300px; max-width: 300px;\"><table id=\"properties\" style=\"width: 300px; table-layout: fixed;\"><colgroup><col style=\"width: 35%;\"><col style=\"width: 65%;\"></colgroup></table></div>";
|
||||
|
||||
property("Type", selected.nodeName);
|
||||
property("Id", selected.id);
|
||||
|
||||
property("Display",
|
||||
"<select id=\"display\" style=\"width: 100%; float: right;\">" +
|
||||
" <option value=\"inline\">Inline</option>" +
|
||||
" <option value=\"block\">Block</option>" +
|
||||
" <option value=\"inline-block\">Inline Block</option>" +
|
||||
" <option value=\"none\">None</option>" +
|
||||
"</select>",
|
||||
"display",
|
||||
() => { document.getElementById('display').value = selected.style.display; },
|
||||
() => { selected.style.display = document.getElementById('display').value; }
|
||||
);
|
||||
|
||||
if(selected.id != "mainpage") {
|
||||
|
||||
heading("Geometry");
|
||||
|
||||
property("Position",
|
||||
"<select id=\"position\" style=\"width: 100%; float: right;\">" +
|
||||
" <option value=\"absolute\">Absolute</option>" +
|
||||
" <option value=\"static\">Static</option>" +
|
||||
" <option value=\"relative\">Relative</option>" +
|
||||
"</select>",
|
||||
"position",
|
||||
() => { document.getElementById('position').value = selected.style.position; },
|
||||
() => { saveUndo();
|
||||
selected.style.position = document.getElementById('position').value;
|
||||
if(document.getElementById('position').value == 'absolute') {
|
||||
selected.style.left = selected.getBoundingClientRect().x + 'px';
|
||||
selected.style.top = selected.getBoundingClientRect().y + 'px';
|
||||
}
|
||||
displayParameters();
|
||||
}
|
||||
);
|
||||
|
||||
if(selected.style.position == 'absolute') {
|
||||
propsize("Left", "left");
|
||||
propsize("Top", "top");
|
||||
}
|
||||
propsize("Width", "width");
|
||||
propsize("Height", "height");
|
||||
}
|
||||
|
||||
if(selected.nodeName != 'IMG') {
|
||||
heading("Font");
|
||||
propcolor("Color", "color");
|
||||
}
|
||||
|
||||
heading("Margins");
|
||||
propsize("Left", "margin-left");
|
||||
propsize("Top", "margin-top");
|
||||
propsize("Right", "margin-right");
|
||||
propsize("Bottom", "margin-bottom");
|
||||
|
||||
if(selected.id != "mainpage") {
|
||||
heading("Border");
|
||||
propsize("Width", "border-width");
|
||||
propcolor("Color", "border-color");
|
||||
}
|
||||
|
||||
heading("Background");
|
||||
propcolor("Color", "background-color");
|
||||
|
||||
heading("Padding");
|
||||
propsize("Left", "padding-left");
|
||||
propsize("Top", "padding-top");
|
||||
propsize("Right", "padding-right");
|
||||
propsize("Bottom", "padding-bottom");
|
||||
}
|
||||
|
||||
function newImage(filename, e) {
|
||||
saveUndo();
|
||||
let img = '<img id="newitem" src="/assets/' + filename + '" style="width: 150px;">';
|
||||
mainpage.insertAdjacentHTML('beforeend', img);
|
||||
}
|
||||
|
||||
function handleFiles(files) {
|
||||
}
|
||||
|
||||
function b64encode(str) {
|
||||
return btoa(unescape(encodeURIComponent(str)));
|
||||
}
|
||||
|
||||
function save(form) {
|
||||
form.html.value = b64encode(document.getElementById('mainpage').innerHTML);
|
||||
form.exit.value = '';
|
||||
form.submit();
|
||||
}
|
||||
|
||||
function savenexit(form) {
|
||||
form.html.value = b64encode(document.getElementById('mainpage').innerHTML);
|
||||
form.exit.value = 'yes';
|
||||
form.submit();
|
||||
}
|
||||
|
||||
function exitnosave(form) {
|
||||
form.html.value = '';
|
||||
form.exit.value = 'yes';
|
||||
form.submit();
|
||||
}
|
||||
Reference in new issue
Block a user