Skip to content

Commit 96f0ba5

Browse files
committed
Don't allow dropping components inside v-attribute elements, translate text dialog, show action buttons bellow selected element when they are not visible above
1 parent b7d19ff commit 96f0ba5

File tree

1 file changed

+101
-30
lines changed

1 file changed

+101
-30
lines changed

public/js/vvvebjs/builder.js

+101-30
Original file line numberDiff line numberDiff line change
@@ -1347,12 +1347,22 @@ Vvveb.Builder = {
13471347

13481348
try {
13491349
let pos = offset(target);
1350+
let top = (pos.top - (self.frameDoc.scrollTop ?? 0) - self.selectPadding);
13501351

1351-
SelectBox.style.top = (pos.top - (self.frameDoc.scrollTop ?? 0) - self.selectPadding) + "px";
1352+
SelectBox.style.top = top + "px";
13521353
SelectBox.style.left = (pos.left - (self.frameDoc.scrollLeft ?? 0) - self.selectPadding) + "px";
13531354
SelectBox.style.width = ((target.offsetWidth ?? target.clientWidth) + self.selectPadding * 2) + "px";
13541355
SelectBox.style.height = ((target.offsetHeight ?? target.clientHeight) + self.selectPadding * 2) + "px";
13551356
SelectBox.style.display = "block";
1357+
1358+
//move actions toolbar to bottom if there is no space on top
1359+
if (top < 30) {
1360+
SelectActions.style.top = "unset";
1361+
SelectActions.style.bottom = "-25px";
1362+
} else {
1363+
SelectActions.style.top = "";
1364+
SelectActions.style.bottom = "";
1365+
}
13561366

13571367
Vvveb.Breadcrumb.loadBreadcrumb(target);
13581368

@@ -1468,7 +1478,7 @@ Vvveb.Builder = {
14681478
br: true,
14691479
wbr: true
14701480
};
1471-
1481+
14721482
let parent = self.highlightEl;
14731483

14741484
if (self.dragType == "section") {
@@ -1477,11 +1487,18 @@ Vvveb.Builder = {
14771487
}
14781488

14791489
let parentTagName = parent.tagName.toLowerCase();
1480-
1490+
let isVattribute = false;
1491+
//check if node is a data-v-attribute dynamic node that will overrite the content if added inside
1492+
for (let attr of parent.attributes) {
1493+
if (attr.name.indexOf("data-v-") == 0) {
1494+
isVattribute = true;
1495+
false;
1496+
}
1497+
}
14811498

14821499
try {
14831500
if ((pos.top < (y - halfHeight)) || (pos.left < (x - halfWidth))) {
1484-
if (noChildren[parentTagName]) {
1501+
if (noChildren[parentTagName] || isVattribute) {
14851502
parent.after(self.dragElement);
14861503
} else {
14871504
if (parent == self.dragElement.parenNode) {
@@ -1493,7 +1510,7 @@ Vvveb.Builder = {
14931510

14941511
prepend = true;
14951512
} else {
1496-
if (noChildren[parentTagName]) {
1513+
if (noChildren[parentTagName] || isVattribute) {
14971514
parent.parentNode.insertBefore(self.dragElement, parent);
14981515
} else {
14991516
parent.prepend(self.dragElement);
@@ -1827,15 +1844,59 @@ Vvveb.Builder = {
18271844

18281845
document.getElementById("translate-code-btn")?.addEventListener("click", function(event) {
18291846
let selectedEl = Vvveb.Builder.selectedEl;
1830-
let value = selectedEl.innerHTML.trim();
1847+
let text = selectedEl.innerHTML.trim();
18311848
// uncomment to use outerHTML, not recommended
1832-
//let value = selectedEl.outerHTML;
1849+
//let text = selectedEl.outerHTML;
1850+
1851+
fetch(namespaceUrl + "/translate&action=get", {method: "POST", body: new URLSearchParams({text})})
1852+
.then((response) => {
1853+
if (!response.ok) { throw new Error(response) }
1854+
return response.json()
1855+
})
1856+
.then((data) => {
1857+
for (code in data) {
1858+
let translation = data[code];
1859+
document.querySelector("#lang-" + code + "-editor textarea").value = translation;
1860+
}
1861+
})
1862+
.catch(error => {
1863+
console.log(error.statusText);
1864+
displayToast("bg-danger", "Error", "Error loading translations!");
1865+
});
1866+
1867+
18331868
Vvveb.ModalTranslateEditor.show();
1834-
Vvveb.ModalTranslateEditor.setValue(value);
1869+
Vvveb.ModalTranslateEditor.setValue(text);
18351870

18361871
let onSave = function(event) {
1872+
let data = Object.fromEntries(new FormData(document.getElementById("translateForm")));
1873+
1874+
fetch(namespaceUrl + "/translate&action=save", {method: "POST", body: new URLSearchParams(data)})
1875+
.then((response) => {
1876+
if (!response.ok) { throw new Error(response) }
1877+
return response.json()
1878+
})
1879+
.then((data) => {
1880+
let bg = "bg-success";
1881+
1882+
if (data.success || text == "success") {
1883+
} else {
1884+
bg = "bg-danger";
1885+
}
1886+
1887+
displayToast(bg, "Save", data.message ?? data);
1888+
})
1889+
.catch(error => {
1890+
console.log(error.statusText);
1891+
displayToast("bg-danger", "Error", "Error saving translations!");
1892+
});
1893+
/*
1894+
Vvveb.Builder.frameBody.querySelectorAll("form").forEach(f => {
1895+
console.log( JSON.stringify(Object.fromEntries(new FormData(f))) );
1896+
});
1897+
*/
18371898
selectedEl.innerHTML = event.detail;
1838-
//selectedEl.outerHTML = value;
1899+
//selectedEl.outerHTML = text;
18391900
};
18401901

18411902
window.removeEventListener("vvveb.ModalTranslateEditor.save", onSave);
@@ -1851,12 +1912,14 @@ Vvveb.Builder = {
18511912
node = self.selectedEl;
18521913

18531914
Vvveb.Undo.addMutation({type: 'childList',
1854-
target: node.parentNode,
1855-
removedNodes: [node],
1856-
nextSibling: node.nextSibling});
1915+
target: node.parentNode,
1916+
removedNodes: [node],
1917+
nextSibling: node.nextSibling});
18571918

18581919
self.selectedEl.remove();
1859-
1920+
Vvveb.TreeList.loadComponents();
1921+
Vvveb.SectionList.loadSections();
1922+
18601923
event.preventDefault();
18611924
return false;
18621925
});
@@ -2243,6 +2306,7 @@ Vvveb.Builder = {
22432306
Vvveb.ModalCodeEditor = {
22442307
modal: false,
22452308
modalId: 'codeEditorModal',
2309+
name: 'ModalCodeEditor',
22462310
editor: false,
22472311

22482312
init: function(modal = false, editor = false) {
@@ -2260,7 +2324,7 @@ Vvveb.ModalCodeEditor = {
22602324
let self = this;
22612325

22622326
this.modal.querySelector('.save-btn').addEventListener("click", function(event) {
2263-
window.dispatchEvent(new CustomEvent("vvveb.ModalCodeEditor.save", {detail: self.getValue()}));
2327+
window.dispatchEvent(new CustomEvent("vvveb." + self.name + ".save", {detail: self.getValue()}));
22642328
self.hide();
22652329
return false;
22662330
});
@@ -2295,6 +2359,7 @@ Vvveb.ModalCodeEditor = {
22952359
//Vvveb.ModalTranslateEditor = structuredClone(Vvveb.ModalCodeEditor);
22962360
Vvveb.ModalTranslateEditor = Object.assign({}, Vvveb.ModalCodeEditor);
22972361
Vvveb.ModalTranslateEditor.modalId = 'translateEditorModal';
2362+
Vvveb.ModalTranslateEditor.name = 'ModalTranslateEditor';
22982363

22992364
Vvveb.CodeEditor = {
23002365

@@ -2427,7 +2492,7 @@ Vvveb.Gui = {
24272492
folder = (folder = /(.+)\//.exec(filename)) ? folder[1] : '/';
24282493

24292494
page = Vvveb.FileManager.getCurrentUrl();
2430-
page = (page = /[^\/]+$/.exec(page)) ? page[0] : '';
2495+
page = (page = /[^\/]+\?$/.exec(page)) ? page[0] : '';
24312496
page = page.replace(".html", "");
24322497
page = page ? page : "new-template";
24332498
page += ".html";
@@ -2702,7 +2767,7 @@ Vvveb.Gui = {
27022767
setState: function () {
27032768
Vvveb.StyleManager.setState(this.value);
27042769
Vvveb.Builder.reloadComponent();
2705-
}
2770+
}
27062771
}
27072772

27082773
Vvveb.StyleManager = {
@@ -2930,7 +2995,7 @@ Vvveb.StyleManager = {
29302995

29312996
el = element;
29322997
if (el != this.currentElement) {
2933-
selector = this.getSelectorForElement(el);
2998+
selector = this.getSelectorForElement(el);
29342999
this.currentElement = el;
29353000
this.currentSelector = selector
29363001
} else {
@@ -3152,6 +3217,7 @@ Vvveb.SectionList = {
31523217
let node = section._node;
31533218
node.remove();
31543219
section.remove();
3220+
Vvveb.TreeList.loadComponents();
31553221

31563222
e.stopPropagation();
31573223
e.preventDefault();
@@ -3316,8 +3382,9 @@ Vvveb.SectionList = {
33163382

33173383
loadSections: function() {
33183384
let sections = this.getSections();
3385+
let container = document.querySelector(this.selector);
33193386

3320-
document.querySelector(this.selector).replaceChildren();
3387+
container.replaceChildren();
33213388
for (i in sections) {
33223389
this.addSection(sections[i]);
33233390
}
@@ -3600,7 +3667,7 @@ Vvveb.FileManager = {
36003667

36013668
deletePage: function(element, e) {
36023669
let page = element.dataset;
3603-
let post_id = element.dataset.post_id;
3670+
let post_id = element.dataset.post_id ?? 0;
36043671
let name;
36053672
let _self = this;
36063673

@@ -3651,14 +3718,15 @@ Vvveb.FileManager = {
36513718
},
36523719

36533720
renamePage: function(element, e, duplicate = false) {
3654-
let page = element.dataset;
3655-
let post_id = element.dataset.post_id ?? 0;
3721+
let page = element.dataset;
3722+
let post_id = element.dataset.post_id ?? 0;
3723+
let product_id = element.dataset.product_id ?? 0;
36563724
let newfile;
36573725
let name;
36583726
let _self = this;
36593727

36603728
name = element.querySelector('label span')?.textContent.replace('.html', '');
3661-
if (post_id) {
3729+
if (post_id || product_id) {
36623730
name = prompt(`Enter new name for "${name}"`, name);
36633731
if (name) {
36643732
newfile = page.file;
@@ -3675,7 +3743,7 @@ Vvveb.FileManager = {
36753743

36763744
if (page) {
36773745

3678-
fetch(renameFileUrl, {method: "POST", body: new URLSearchParams({file:page.file, newfile:newfile, name, duplicate, post_id})})
3746+
fetch(renameFileUrl, {method: "POST", body: new URLSearchParams({file:page.file, newfile:newfile, name, duplicate, post_id, product_id})})
36793747
.then((response) => {
36803748
if (!response.ok) { return Promise.reject(response); }
36813749
return response.json()
@@ -3691,17 +3759,20 @@ Vvveb.FileManager = {
36913759
newfile = data.newfile ?? newfile;
36923760
displayToast(bg, "Rename", data.message ?? data);
36933761
let baseName = newfile.replace('.html', '');
3694-
let newName = name || friendlyName(newfile.replace(/.*[\/\\]+/, '')).replace('.html', '');
3762+
let newName = data.name ?? name ?? friendlyName(newfile.replace(/.*[\/\\]+/, '')).replace('.html', '');
36953763

36963764
if (duplicate) {
36973765
let addPage = _self.pages[page.page];
3698-
addPage["name"] = baseName;
3699-
addPage["file"] = newfile;
3700-
addPage["title"] = newName;
3701-
addPage["url"] = data.url;
3766+
addPage["name"] = data.name ?? baseName;
3767+
addPage["file"] = newfile;
3768+
addPage["title"] = newName;
3769+
addPage["url"] = data.url;
3770+
addPage["post_id"] = data.post_id;
3771+
addPage["product_id"] = data.product_id;
3772+
37023773
if (data.newfile) {
37033774
//addPage["url"] = Vvveb.themeBaseUrl + addPage["url"]
3704-
addPage["url"] = page.url.substring(0, page.url.lastIndexOf("/") + 1) + addPage["url"];
3775+
//addPage["url"] = page.url.substring(0, page.url.lastIndexOf("/") + 1) + addPage["url"];
37053776
}
37063777

37073778
let newPage = Vvveb.FileManager.addPage(baseName, addPage, page.page);
@@ -4050,7 +4121,7 @@ Vvveb.FontsManager = {
40504121

40514122
activeFonts:[],
40524123
providers: {},//{"google":GoogleFontsManager};
4053-
4124+
40544125
addFontList: function(provider, groupName, fontList) {
40554126
let fonts = {};
40564127
let fontNames = [];

0 commit comments

Comments
 (0)