mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
Merge pull request #741 from Azgaar/rich-notes-editor
Rich notes editor [tiny.cloud]
This commit is contained in:
commit
5aca8ce82e
7 changed files with 156 additions and 152 deletions
76
index.css
76
index.css
|
|
@ -2036,7 +2036,7 @@ div.textual span,
|
||||||
fill: none;
|
fill: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#notes {
|
#notes {
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: 28vw;
|
width: 28vw;
|
||||||
|
|
@ -2046,22 +2046,47 @@ div#notes {
|
||||||
border: 1px solid #5e4fa2;
|
border: 1px solid #5e4fa2;
|
||||||
background: rgba(255, 250, 228, 0.7);
|
background: rgba(255, 250, 228, 0.7);
|
||||||
box-shadow: 2px 2px 5px -3px #3a2804;
|
box-shadow: 2px 2px 5px -3px #3a2804;
|
||||||
white-space: pre-line;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
div#notesHeader {
|
@media screen and (max-width: 600px) {
|
||||||
|
#notes {
|
||||||
|
width: 50vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#notesHeader {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 1.3em;
|
font-size: 1.3em;
|
||||||
padding: 0 0 4px 14px;
|
padding: 16px 0 4px 12px;
|
||||||
border-bottom: 1px solid #5e4fa2;
|
border-bottom: 1px solid #5e4fa2;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#notesBody {
|
#notesBody {
|
||||||
padding: 0 1em;
|
padding: 14px 12px;
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#notesBody > iframe {
|
||||||
|
pointer-events: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notesBody p {
|
||||||
|
margin: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notesLegend {
|
||||||
|
height: 87%;
|
||||||
|
outline: 0;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 0.6em;
|
||||||
|
font-family: Copperplate, monospace;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #dedede;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
svg.button {
|
svg.button {
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
@ -2318,45 +2343,6 @@ svg.button {
|
||||||
stroke-width: 0;
|
stroke-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pell {
|
|
||||||
border: 1px solid hsla(0, 0%, 4%, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pell,
|
|
||||||
.pell-content {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pell-content {
|
|
||||||
height: 14em;
|
|
||||||
outline: 0;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 0.6em;
|
|
||||||
font-family: Copperplate, monospace;
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #dedede;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pell-actionbar {
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #dedede;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pell-button {
|
|
||||||
background-color: transparent;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
height: 30px;
|
|
||||||
outline: 0;
|
|
||||||
width: 30px;
|
|
||||||
vertical-align: bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pell-button-selected {
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#debug {
|
#debug {
|
||||||
font-size: 1px;
|
font-size: 1px;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
|
|
|
||||||
19
index.html
19
index.html
|
|
@ -2911,22 +2911,20 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="notesEditor" class="dialog stable textual" style="display: none">
|
<div id="notesEditor" class="dialog stable" style="display: none">
|
||||||
<div>
|
<div style="margin-bottom: 0.3em">
|
||||||
<span>Select object: </span>
|
<strong>Element: </strong>
|
||||||
<select id="notesSelect" data-tip="Select object" style="width: 12em"></select>
|
<select id="notesSelect" data-tip="Select element id" style="width: 12em"></select>
|
||||||
<span>Object name: </span>
|
<strong>Element name: </strong>
|
||||||
<input id="notesName" data-tip="Type to change object name" autocorrect="off" spellcheck="false" style="width: 16em">
|
<input id="notesName" data-tip="Set element name" autocorrect="off" spellcheck="false" style="width: 16em">
|
||||||
<span data-tip="Speak the name. You can change voice and language in options" class="speaker">🔊</span>
|
<span data-tip="Speak the name. You can change voice and language in options" class="speaker">🔊</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="notesText" data-tip="Type and style object description" style="padding: .4em 0"></div>
|
<div id="notesLegend" contenteditable="true"></div>
|
||||||
<div>
|
<div style="margin-top: 0.3em">
|
||||||
<button id="notesSpeak" data-tip="Speak the note. You can change voice and language in options" class="icon-voice"></button>
|
|
||||||
<button id="notesFocus" data-tip="Focus on selected object" class="icon-target"></button>
|
<button id="notesFocus" data-tip="Focus on selected object" class="icon-target"></button>
|
||||||
<button id="notesPin" data-tip="Toggle notes box dispay: hide or do not hide the box on mouse move" class="icon-pin"></button>
|
<button id="notesPin" data-tip="Toggle notes box dispay: hide or do not hide the box on mouse move" class="icon-pin"></button>
|
||||||
<button id="notesDownload" data-tip="Download notes to PC" class="icon-download"></button>
|
<button id="notesDownload" data-tip="Download notes to PC" class="icon-download"></button>
|
||||||
<button id="notesUpload" data-tip="Upload notes from PC" class="icon-upload"></button>
|
<button id="notesUpload" data-tip="Upload notes from PC" class="icon-upload"></button>
|
||||||
<button id="notesClearStyle" data-tip="Remove all styling, get plain text only" class="icon-eraser"></button>
|
|
||||||
<button id="notesRemove" data-tip="Remove this note" class="icon-trash fastDelete"></button>
|
<button id="notesRemove" data-tip="Remove this note" class="icon-trash fastDelete"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -4549,7 +4547,6 @@
|
||||||
<script defer src="modules/coa-renderer.js"></script>
|
<script defer src="modules/coa-renderer.js"></script>
|
||||||
<script defer src="libs/rgbquant.min.js"></script>
|
<script defer src="libs/rgbquant.min.js"></script>
|
||||||
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
<script defer src="libs/jquery.ui.touch-punch.min.js"></script>
|
||||||
<script defer src="libs/pell.min.js"></script>
|
|
||||||
<script defer src="libs/jszip.min.js"></script>
|
<script defer src="libs/jszip.min.js"></script>
|
||||||
|
|
||||||
<script defer src="modules/io/save.js"></script>
|
<script defer src="modules/io/save.js"></script>
|
||||||
|
|
|
||||||
2
libs/pell.min.js
vendored
2
libs/pell.min.js
vendored
|
|
@ -1,2 +0,0 @@
|
||||||
// https://github.com/jaredreich/pell, MIT License
|
|
||||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Pell=t()}(this,function(){"use strict";const e=(e,t,n)=>e.addEventListener(t,n),t=(e,t)=>e.appendChild(t),n=e=>document.createElement(e),i=e=>document.queryCommandState(e),o=(e,t=null)=>document.execCommand(e,!1,t),l={bold:{icon:"<b>B</b>",title:"Bold",state:()=>i("bold"),result:()=>o("bold")},italic:{icon:"<i>I</i>",title:"Italic",state:()=>i("italic"),result:()=>o("italic")},underline:{icon:"<u>U</u>",title:"Underline",state:()=>i("underline"),result:()=>o("underline")},strikethrough:{icon:"<strike>S</strike>",title:"Strike-through",state:()=>i("strikeThrough"),result:()=>o("strikeThrough")},heading1:{icon:"<b>H<sub>1</sub></b>",title:"Heading 1",result:()=>o("formatBlock","<h1>")},heading2:{icon:"<b>H<sub>2</sub></b>",title:"Heading 2",result:()=>o("formatBlock","<h2>")},paragraph:{icon:"¶",title:"Paragraph",result:()=>o("formatBlock","<p>")},quote:{icon:"“ ”",title:"Quote",result:()=>o("formatBlock","<blockquote>")},olist:{icon:"#",title:"Ordered List",result:()=>o("insertOrderedList")},ulist:{icon:"•",title:"Unordered List",result:()=>o("insertUnorderedList")},code:{icon:"</>",title:"Code",result:()=>o("formatBlock","<pre>")},line:{icon:"―",title:"Horizontal Line",result:()=>o("insertHorizontalRule")},link:{icon:"🔗",title:"Link",result:()=>navigator.clipboard.readText().then(e=>o("createLink",e))},image:{icon:"📷",title:"Image",result:()=>{navigator.clipboard.readText().then(e=>o("insertImage",e)),o("enableObjectResizing")}}},r={actionbar:"pell-actionbar",button:"pell-button",content:"pell-content",selected:"pell-button-selected"};return{exec:o,init:i=>{const a=i.actions?i.actions.map(e=>"string"==typeof e?l[e]:l[e.name]?{...l[e.name],...e}:e):Object.keys(l).map(e=>l[e]),s={...r,...i.classes},c=i.defaultParagraphSeparator||"div",u=n("div");u.className=s.actionbar,t(i.element,u);const d=i.element.content=n("div");return d.contentEditable=!0,d.className=s.content,d.oninput=(({target:{firstChild:e}})=>{e&&3===e.nodeType?o("formatBlock",`<${c}>`):"<br>"===d.innerHTML&&(d.innerHTML=""),i.onChange(d.innerHTML)}),d.onkeydown=(e=>{"Enter"===e.key&&"blockquote"===(e=>document.queryCommandValue(e))("formatBlock")&&setTimeout(()=>o("formatBlock",`<${c}>`),0)}),t(i.element,d),a.forEach(i=>{const o=n("button");if(o.className=s.button,o.innerHTML=i.icon,o.title=i.title,o.setAttribute("type","button"),o.onclick=(()=>i.result()&&d.focus()),i.state){const t=()=>o.classList[i.state()?"add":"remove"](s.selected);e(d,"keyup",t),e(d,"mouseup",t),e(o,"click",t)}t(u,o)}),i.styleWithCSS&&o("styleWithCSS"),o("defaultParagraphSeparator",c),i.element}}});
|
|
||||||
8
main.js
8
main.js
|
|
@ -2,7 +2,7 @@
|
||||||
// https://github.com/Azgaar/Fantasy-Map-Generator
|
// https://github.com/Azgaar/Fantasy-Map-Generator
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
const version = "1.73"; // generator version
|
const version = "1.731"; // generator version
|
||||||
document.title += " v" + version;
|
document.title += " v" + version;
|
||||||
|
|
||||||
// switches to disable/enable logging features
|
// switches to disable/enable logging features
|
||||||
|
|
@ -434,9 +434,10 @@ function showWelcomeMessage() {
|
||||||
const discord = link("https://discordapp.com/invite/X7E84HU", "Discord server");
|
const discord = link("https://discordapp.com/invite/X7E84HU", "Discord server");
|
||||||
const patreon = link("https://www.patreon.com/azgaar", "Patreon");
|
const patreon = link("https://www.patreon.com/azgaar", "Patreon");
|
||||||
|
|
||||||
alertMessage.innerHTML = `The Fantasy Map Generator is updated up to version <b>${version}</b>.
|
alertMessage.innerHTML = `The Fantasy Map Generator is updated up to version <strong>${version}</strong>.
|
||||||
This version is compatible with ${changelog}, loaded <i>.map</i> files will be auto-updated.
|
This version is compatible with ${changelog}, loaded <i>.map</i> files will be auto-updated.
|
||||||
<ul><b>Latest changes:</b>
|
<ul><strong>Latest changes:</strong>
|
||||||
|
<li>Advanced notes editor</li>
|
||||||
<li>Zones editor: filter by type</li>
|
<li>Zones editor: filter by type</li>
|
||||||
<li>Color picker: new hatchings</li>
|
<li>Color picker: new hatchings</li>
|
||||||
<li>New style presets: Cyberpunk and Atlas</li>
|
<li>New style presets: Cyberpunk and Atlas</li>
|
||||||
|
|
@ -444,7 +445,6 @@ function showWelcomeMessage() {
|
||||||
<li>4 new textures</li>
|
<li>4 new textures</li>
|
||||||
<li>Province capture logic rework</li>
|
<li>Province capture logic rework</li>
|
||||||
<li>Button to release all provinces</li>
|
<li>Button to release all provinces</li>
|
||||||
<li>Limit military units by biome, state, culture and religion</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>Join our ${discord} and ${reddit} to ask questions, share maps, discuss the Generator and Worlbuilding, report bugs and propose new features.</p>
|
<p>Join our ${discord} and ${reddit} to ask questions, share maps, discuss the Generator and Worlbuilding, report bugs and propose new features.</p>
|
||||||
|
|
|
||||||
|
|
@ -519,7 +519,7 @@ window.Markers = (function () {
|
||||||
|
|
||||||
const dungeonSeed = `${seed}${cell}`;
|
const dungeonSeed = `${seed}${cell}`;
|
||||||
const name = "Dungeon";
|
const name = "Dungeon";
|
||||||
const legend = `<div>Undiscovered dungeon. See <a href="https://watabou.github.io/one-page-dungeon/?seed=${dungeonSeed}" target="_blank">One page dungeon</a></div><iframe style="height: 33vh" src="https://watabou.github.io/one-page-dungeon/?seed=${dungeonSeed}" sandbox="allow-scripts allow-same-origin"></iframe>`;
|
const legend = `<div>Undiscovered dungeon. See <a href="https://watabou.github.io/one-page-dungeon/?seed=${dungeonSeed}" target="_blank">One page dungeon</a></div><iframe src="https://watabou.github.io/one-page-dungeon/?seed=${dungeonSeed}" sandbox="allow-scripts allow-same-origin"></iframe>`;
|
||||||
notes.push({id, name, legend});
|
notes.push({id, name, legend});
|
||||||
quantity--;
|
quantity--;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,8 @@ function mouseMove() {
|
||||||
const point = d3.mouse(this);
|
const point = d3.mouse(this);
|
||||||
const i = findCell(point[0], point[1]); // pack cell id
|
const i = findCell(point[0], point[1]); // pack cell id
|
||||||
if (i === undefined) return;
|
if (i === undefined) return;
|
||||||
showNotes(d3.event, i);
|
|
||||||
|
showNotes(d3.event);
|
||||||
const g = findGridCell(point[0], point[1]); // grid cell id
|
const g = findGridCell(point[0], point[1]); // grid cell id
|
||||||
if (tooltip.dataset.main) showMainTip();
|
if (tooltip.dataset.main) showMainTip();
|
||||||
else showMapTooltip(point, d3.event, i, g);
|
else showMapTooltip(point, d3.event, i, g);
|
||||||
|
|
@ -78,7 +79,7 @@ function mouseMove() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// show note box on hover (if any)
|
// show note box on hover (if any)
|
||||||
function showNotes(e, i) {
|
function showNotes(e) {
|
||||||
if (notesEditor.offsetParent) return;
|
if (notesEditor.offsetParent) return;
|
||||||
let id = e.target.id || e.target.parentNode.id || e.target.parentNode.parentNode.id;
|
let id = e.target.id || e.target.parentNode.id || e.target.parentNode.parentNode.id;
|
||||||
if (e.target.parentNode.parentNode.id === "burgLabels") id = "burg" + e.target.dataset.id;
|
if (e.target.parentNode.parentNode.id === "burgLabels") id = "burg" + e.target.dataset.id;
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,22 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function editNotes(id, name) {
|
function editNotes(id, name) {
|
||||||
|
// elements
|
||||||
|
const notesLegend = document.getElementById("notesLegend");
|
||||||
|
const notesName = document.getElementById("notesName");
|
||||||
|
const notesSelect = document.getElementById("notesSelect");
|
||||||
|
const notesPin = document.getElementById("notesPin");
|
||||||
|
|
||||||
// update list of objects
|
// update list of objects
|
||||||
const select = document.getElementById("notesSelect");
|
notesSelect.options.length = 0;
|
||||||
select.options.length = 0;
|
|
||||||
for (const note of notes) {
|
for (const note of notes) {
|
||||||
select.options.add(new Option(note.id, note.id));
|
notesSelect.options.add(new Option(note.id, note.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
// initiate pell (html editor)
|
// update pin notes icon
|
||||||
const notesText = document.getElementById("notesText");
|
const notesArePinned = options.pinNotes;
|
||||||
notesText.innerHTML = "";
|
if (notesArePinned) notesPin.classList.add("pressed");
|
||||||
const editor = Pell.init({
|
else notesPin.classList.remove("pressed");
|
||||||
element: notesText,
|
|
||||||
onChange: html => {
|
|
||||||
const note = notes.find(note => note.id === select.value);
|
|
||||||
if (!note) return;
|
|
||||||
note.legend = html;
|
|
||||||
showNote(note);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// select an object
|
// select an object
|
||||||
if (notes.length || id) {
|
if (notes.length || id) {
|
||||||
|
|
@ -29,136 +26,161 @@ function editNotes(id, name) {
|
||||||
if (!name) name = id;
|
if (!name) name = id;
|
||||||
note = {id, name, legend: ""};
|
note = {id, name, legend: ""};
|
||||||
notes.push(note);
|
notes.push(note);
|
||||||
select.options.add(new Option(id, id));
|
notesSelect.options.add(new Option(id, id));
|
||||||
}
|
}
|
||||||
select.value = id;
|
|
||||||
notesName.value = note.name;
|
notesSelect.value = id;
|
||||||
editor.content.innerHTML = note.legend;
|
notesName.value = note.name;
|
||||||
showNote(note);
|
notesLegend.innerHTML = note.legend;
|
||||||
} else {
|
initEditor();
|
||||||
editor.content.innerHTML = "There are no added notes. Click on element (e.g. label) and add a free text note";
|
updateNotesBox(note);
|
||||||
document.getElementById("notesName").value = "";
|
} else {
|
||||||
|
// if notes array is empty
|
||||||
|
notesName.value = "";
|
||||||
|
notesLegend.innerHTML = "No notes added. Click on an element (e.g. label or marker) and add a free text note";
|
||||||
}
|
}
|
||||||
|
|
||||||
// open a dialog
|
|
||||||
$("#notesEditor").dialog({
|
$("#notesEditor").dialog({
|
||||||
title: "Notes Editor",
|
title: "Notes Editor",
|
||||||
minWidth: "40em",
|
width: "70vw",
|
||||||
width: "50vw",
|
height: window.innerHeight * 0.75,
|
||||||
position: {my: "center", at: "center", of: "svg"}
|
position: {my: "center", at: "center", of: "svg"},
|
||||||
|
close: removeEditor
|
||||||
});
|
});
|
||||||
|
$("[aria-describedby='notesEditor']").css("top", "10vh");
|
||||||
|
|
||||||
if (modules.editNotes) return;
|
if (modules.editNotes) return;
|
||||||
modules.editNotes = true;
|
modules.editNotes = true;
|
||||||
|
|
||||||
// add listeners
|
// add listeners
|
||||||
document.getElementById("notesSelect").addEventListener("change", changeObject);
|
document.getElementById("notesSelect").addEventListener("change", changeElement);
|
||||||
document.getElementById("notesName").addEventListener("input", changeName);
|
document.getElementById("notesName").addEventListener("input", changeName);
|
||||||
document.getElementById("notesPin").addEventListener("click", () => (options.pinNotes = !options.pinNotes));
|
document.getElementById("notesLegend").addEventListener("blur", updateLegend);
|
||||||
document.getElementById("notesSpeak").addEventListener("click", () => speak(editor.content.innerHTML));
|
document.getElementById("notesPin").addEventListener("click", toggleNotesPin);
|
||||||
document.getElementById("notesFocus").addEventListener("click", validateHighlightElement);
|
document.getElementById("notesFocus").addEventListener("click", validateHighlightElement);
|
||||||
document.getElementById("notesDownload").addEventListener("click", downloadLegends);
|
document.getElementById("notesDownload").addEventListener("click", downloadLegends);
|
||||||
document.getElementById("notesUpload").addEventListener("click", () => legendsToLoad.click());
|
document.getElementById("notesUpload").addEventListener("click", () => legendsToLoad.click());
|
||||||
document.getElementById("legendsToLoad").addEventListener("change", function () {
|
document.getElementById("legendsToLoad").addEventListener("change", function () {
|
||||||
uploadFile(this, uploadLegends);
|
uploadFile(this, uploadLegends);
|
||||||
});
|
});
|
||||||
document.getElementById("notesClearStyle").addEventListener("click", clearStyle);
|
|
||||||
document.getElementById("notesRemove").addEventListener("click", triggerNotesRemove);
|
document.getElementById("notesRemove").addEventListener("click", triggerNotesRemove);
|
||||||
|
|
||||||
function showNote(note) {
|
async function initEditor() {
|
||||||
document.getElementById("notes").style.display = "block";
|
if (!window.tinymce) {
|
||||||
|
const url = "https://cdn.tiny.cloud/1/4i6a79ymt2y0cagke174jp3meoi28vyecrch12e5puyw3p9a/tinymce/5/tinymce.min.js";
|
||||||
|
try {
|
||||||
|
await import(url);
|
||||||
|
} catch (error) {
|
||||||
|
// error may be caused by failed request being cached, try again with random hash
|
||||||
|
try {
|
||||||
|
const hash = Math.random().toString(36).substring(2, 15);
|
||||||
|
await import(`${url}#${hash}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.tinymce) {
|
||||||
|
tinymce.init({
|
||||||
|
selector: "#notesLegend",
|
||||||
|
height: "90%",
|
||||||
|
menubar: false,
|
||||||
|
plugins: `autolink lists link charmap print formatpainter casechange code fullscreen image link media table paste hr checklist wordcount`,
|
||||||
|
toolbar: `code | undo redo | bold italic strikethrough | forecolor backcolor | formatpainter removeformat | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media table | fontselect fontsizeselect | blockquote hr casechange checklist charmap | print fullscreen`,
|
||||||
|
media_alt_source: false,
|
||||||
|
media_poster: false,
|
||||||
|
setup: editor => {
|
||||||
|
editor.on("Change", updateLegend);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLegend() {
|
||||||
|
const note = notes.find(note => note.id === notesSelect.value);
|
||||||
|
if (!note) return tip("Note element is not found", true, "error", 4000);
|
||||||
|
|
||||||
|
const isTinyEditorActive = window.tinymce?.activeEditor;
|
||||||
|
note.legend = isTinyEditorActive ? tinymce.activeEditor.getContent() : notesLegend.innerHTML;
|
||||||
|
updateNotesBox(note);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateNotesBox(note) {
|
||||||
document.getElementById("notesHeader").innerHTML = note.name;
|
document.getElementById("notesHeader").innerHTML = note.name;
|
||||||
document.getElementById("notesBody").innerHTML = note.legend;
|
document.getElementById("notesBody").innerHTML = note.legend;
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeObject() {
|
function changeElement() {
|
||||||
const note = notes.find(note => note.id === this.value);
|
const note = notes.find(note => note.id === this.value);
|
||||||
if (!note) return;
|
if (!note) return tip("Note element is not found", true, "error", 4000);
|
||||||
|
|
||||||
notesName.value = note.name;
|
notesName.value = note.name;
|
||||||
editor.content.innerHTML = note.legend;
|
notesLegend.innerHTML = note.legend;
|
||||||
|
updateNotesBox(note);
|
||||||
|
|
||||||
|
if (window.tinymce) tinymce.activeEditor.setContent(note.legend);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeName() {
|
function changeName() {
|
||||||
const id = document.getElementById("notesSelect").value;
|
const note = notes.find(note => note.id === notesSelect.value);
|
||||||
const note = notes.find(note => note.id === id);
|
if (!note) return tip("Note element is not found", true, "error", 4000);
|
||||||
if (!note) return;
|
|
||||||
note.name = this.value;
|
note.name = this.value;
|
||||||
showNote(note);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateHighlightElement() {
|
function validateHighlightElement() {
|
||||||
const select = document.getElementById("notesSelect");
|
const element = document.getElementById(notesSelect.value);
|
||||||
const element = document.getElementById(select.value);
|
if (element) return highlightElement(element, 3);
|
||||||
|
|
||||||
// if element is not found
|
confirmationDialog({
|
||||||
if (element === null) {
|
|
||||||
alertMessage.innerHTML = "Related element is not found. Would you like to remove the note?";
|
|
||||||
$("#alert").dialog({
|
|
||||||
resizable: false,
|
|
||||||
title: "Element not found",
|
title: "Element not found",
|
||||||
buttons: {
|
message: "Note element is not found. Would you like to remove the note?",
|
||||||
Remove: function () {
|
confirm: "Remove",
|
||||||
$(this).dialog("close");
|
cancel: "Keep",
|
||||||
removeLegend();
|
onConfirm: removeLegend
|
||||||
},
|
|
||||||
Keep: function () {
|
|
||||||
$(this).dialog("close");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
highlightElement(element, 3); // if element is found
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function downloadLegends() {
|
function downloadLegends() {
|
||||||
const data = JSON.stringify(notes);
|
const notesData = JSON.stringify(notes);
|
||||||
const name = getFileName("Notes") + ".txt";
|
const name = getFileName("Notes") + ".txt";
|
||||||
downloadFile(data, name);
|
downloadFile(notesData, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function uploadLegends(dataLoaded) {
|
function uploadLegends(dataLoaded) {
|
||||||
if (!dataLoaded) {
|
if (!dataLoaded) return tip("Cannot load the file. Please check the data format", false, "error");
|
||||||
tip("Cannot load the file. Please check the data format", false, "error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
notes = JSON.parse(dataLoaded);
|
notes = JSON.parse(dataLoaded);
|
||||||
document.getElementById("notesSelect").options.length = 0;
|
notesSelect.options.length = 0;
|
||||||
editNotes(notes[0].id, notes[0].name);
|
editNotes(notes[0].id, notes[0].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearStyle() {
|
|
||||||
editor.content.innerHTML = editor.content.textContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
function triggerNotesRemove() {
|
function triggerNotesRemove() {
|
||||||
alertMessage.innerHTML = "Are you sure you want to remove the selected note?";
|
confirmationDialog({
|
||||||
$("#alert").dialog({
|
|
||||||
resizable: false,
|
|
||||||
title: "Remove note",
|
title: "Remove note",
|
||||||
buttons: {
|
message: "Are you sure you want to remove the selected note? There is no way to undo this action",
|
||||||
Remove: function () {
|
confirm: "Remove",
|
||||||
$(this).dialog("close");
|
onConfirm: removeLegend
|
||||||
removeLegend();
|
|
||||||
},
|
|
||||||
Keep: function () {
|
|
||||||
$(this).dialog("close");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeLegend() {
|
function removeLegend() {
|
||||||
const select = document.getElementById("notesSelect");
|
const index = notes.findIndex(n => n.id === notesSelect.value);
|
||||||
const index = notes.findIndex(n => n.id === select.value);
|
|
||||||
notes.splice(index, 1);
|
notes.splice(index, 1);
|
||||||
select.options.length = 0;
|
notesSelect.options.length = 0;
|
||||||
if (!notes.length) {
|
if (!notes.length) {
|
||||||
$("#notesEditor").dialog("close");
|
$("#notesEditor").dialog("close");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
notesText.innerHTML = "";
|
|
||||||
editNotes(notes[0].id, notes[0].name);
|
editNotes(notes[0].id, notes[0].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleNotesPin() {
|
||||||
|
options.pinNotes = !options.pinNotes;
|
||||||
|
this.classList.toggle("pressed");
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeEditor() {
|
||||||
|
if (window.tinymce) tinymce.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue