(() => {
var COMMON_EMBED_COMMANDS = {
navigate: async (app, url) => {
if (await app.navigate(url)) return !0;
try {
return window.open(url, "_blank") != null;
} catch {
return !1;
}
},
prompt: async (app, ...args) => await app.prompt(...args),
alert: async (app, ...args) => await app.alert(...args),
getSettings: async (app) => app.settings,
setSetting: async (app, key, value) => app.setSetting(key, value),
getNoteTitleByUUID: async (app, noteUUID) => {
var _a;
return (_a = await app.notes.find(noteUUID)) == null ? void 0 : _a.name;
},
getNoteContentByUUID: async (app, noteUUID) => await app.notes.find(noteUUID) ? await app.getNoteContent({ uuid: noteUUID }) : null,
getNoteBacklinksByUUID: async (app, noteUUID) => {
var _a;
return await ((_a = await app.notes.find(noteUUID)) == null ? void 0 : _a.backlinks());
},
getNoteTagsByUUID: async (app, noteUUID) => {
var _a;
return (_a = await app.notes.find(noteUUID)) == null ? void 0 : _a.tags;
},
getNoteSections: async (app, ...args) => await app.getNoteSections(...args),
getNoteTasks: async (app, noteHandle, options = {}) => {
let finalOptions = { includeDone: !0, ...options };
return await app.getNoteTasks(noteHandle, finalOptions);
},
insertTask: async (app, ...args) => await app.insertTask(...args),
updateTask: async (app, ...args) => await app.updateTask(...args),
createNote: async (app, ...args) => await app.createNote(...args),
deleteNote: async (app, ...args) => await app.deleteNote(...args),
replaceNoteContent: async (app, ...args) => await app.replaceNoteContent(...args),
setNoteName: async (app, ...args) => await app.setNoteName(...args),
addNoteTag: async (app, ...args) => await app.addNoteTag(...args),
removeNoteTag: async (app, ...args) => await app.removeNoteTag(...args),
insertNoteContent: async (app, ...args) => await app.insertNoteContent(...args),
getTaskDomains: async (app) => await app.getTaskDomains(),
getTaskDomainTasks: async (app, ...args) => await app.getTaskDomainTasks(...args),
getTask: async (app, ...args) => await app.getTask(...args),
findNote: async (app, ...args) => await app.findNote(...args),
filterNotes: async (app, ...args) => await app.filterNotes(...args),
saveFile: async (app, ...args) => {
try {
let { name, data } = args[0];
return data.startsWith("data:") && (data = await (await fetch(data)).blob()), await app.saveFile(data, name);
} catch (e) {
throw e.message;
}
}
};
function createOnEmbedCallHandler(embedCommands = {}, logBlacklistedCommands = []) {
return async function(app, commandName, ...args) {
try {
if (commandName in embedCommands) {
let result = await embedCommands[commandName](app, ...args);
return logBlacklistedCommands.includes(commandName) || console.debug("onEmbedCall:", commandName, args, result), result;
}
} catch (e) {
throw app.alert("Error:", e.message || e), console.error("onEmbedCall:", commandName, args, e), e;
}
throw new Error(`Unknown command: ${commandName}`);
};
}
var plugin = {
resumeResolver: null,
appOption: {
"Publish a tag": async function(app) {
let [tag, optionConfirmEveryNote, optionPublishLinkedNotes, optionCreateHomepage] = await app.prompt(
"Choose the tag you want to publish to the web. Note that all notes with this tag will become public.",
{
inputs: [
{
type: "tags",
label: "Tag to publish"
},
{
type: "checkbox",
label: "Ask me to manually confirm each note before publishing"
},
{
type: "checkbox",
label: "Publish notes linked to from notes in this tag, even if they are not in this tag"
},
{
type: "checkbox",
label: "Also create a homepage/index page, containing a list of links to all of the published notes"
}
]
}
);
if (console.log("tag", tag), console.log("optionConfirmEveryNote", optionConfirmEveryNote), console.log("optionPublishLinkedNotes", optionPublishLinkedNotes), console.log("optionCreateHomepage", optionCreateHomepage), !tag) return;
let noteList = await app.filterNotes({ tag });
console.log("noteList", noteList);
let noteSources = new Map();
for (let note of noteList)
noteSources.set(note.uuid, `#${tag}`);
if (optionPublishLinkedNotes) {
let linkedNotesWithSources = await this.getLinkedNotesFromManyNotes(app, noteList);
console.log("linkedNotes", linkedNotesWithSources);
for (let { note, source } of linkedNotesWithSources)
noteList.push(note), noteSources.set(note.uuid, `\u{1F4D2} Linked from ${source}`);
}
if (optionCreateHomepage) {
let homepageNote = await this.createHomepageNote(app, tag, noteList);
console.log("homepageNote", homepageNote), noteList.push(homepageNote), noteSources.set(homepageNote.uuid, "\u{1F3E0} Homepage");
}
let answer = await app.prompt("Let's double check the list of notes to be published. Uncheck any notes you don't want to publish.", {
inputs: noteList.map((note) => ({
type: "checkbox",
label: `${note.name} (${noteSources.get(note.uuid)})`,
value: !0
}))
});
if (console.log("answer", answer), noteList = noteList.filter((note, index) => answer[index]), console.log("noteList", noteList), optionCreateHomepage) {
let homepageNote = noteList.find((note) => noteSources.get(note.uuid) === "Homepage");
homepageNote && await this.insertHomepageContent(app, homepageNote, tag, noteList.filter((note) => noteSources.get(note.uuid) !== "Homepage"));
}
await this.publishNotes(app, noteList, optionConfirmEveryNote);
},
"Resume webnotes": async function(app) {
if (!this.resumeResolver) {
await app.alert("No publishing process to resume.");
return;
}
this.resumeResolver(), this.resumeResolver = null;
}
},
async getLinkedNotesFromManyNotes(app, noteList) {
console.log("getLinkedNotesFromManyNotes", noteList);
let allLinkedNotesWithSources = [], processedNotes = new Set(), notesToProcess = [...noteList];
for (let note of noteList)
processedNotes.add(note.uuid);
for (; notesToProcess.length > 0; ) {
let currentNote = notesToProcess.shift();
console.log("Processing note for links:", currentNote.name);
let linkedNotes = await this.getLinkedNotesFromNote(app, currentNote);
for (let linkedNote of linkedNotes)
processedNotes.has(linkedNote.uuid) || (console.log("Found new linked note:", linkedNote.name), allLinkedNotesWithSources.push({
note: linkedNote,
source: currentNote.name
}), processedNotes.add(linkedNote.uuid), notesToProcess.push(linkedNote));
}
return allLinkedNotesWithSources;
},
async getLinkedNotesFromNote(app, note) {
console.log("getLinkedNotesFromNote", note);
let noteContent = await app.getNoteContent(note), linkRegex = /\[([^\]]*)\]\(https:\/\/www\.amplenote\.com\/notes\/([a-f0-9-]+)(?:#[^)]+)?\)/g, match, foundUUIDs = new Set();
for (; (match = linkRegex.exec(noteContent)) !== null; ) {
let uuid = match[2];
console.log("uuid", uuid), foundUUIDs.add(uuid);
}
let linkedNotes = Array.from(foundUUIDs), linkedNotesObjects = [];
for (let uuid of linkedNotes) {
let note2 = await app.findNote({ uuid });
linkedNotesObjects.push(note2);
}
return linkedNotesObjects;
},
async createHomepageNote(app, tag, noteList) {
let homepageNote = await app.createNote(`${tag} Homepage`, [tag]);
return await app.findNote({ uuid: homepageNote });
},
async insertHomepageContent(app, homepageNote, tag, noteList) {
let homepageContent = `# ${tag} Homepage
`;
for (let note of noteList)
homepageContent += `- [${note.name}](https://www.amplenote.com/notes/${note.uuid})
`;
await app.insertNoteContent({ uuid: homepageNote.uuid }, homepageContent);
},
async publishNotes(app, noteList, optionConfirmEveryNote) {
let actionToTakeForAllRemainingNotes = null;
for (let note of noteList) {
console.log("note", note);
let action = actionToTakeForAllRemainingNotes;
for (; optionConfirmEveryNote && !actionToTakeForAllRemainingNotes; ) {
let noteDetails = await app.findNote(note), [optionDoTheSameForAllRemainingNotes, userAction] = await app.prompt(
`Do you want to publish ${noteDetails.name}?`,
{
inputs: [
{
type: "checkbox",
label: "Do the same for all remaining notes"
}
],
actions: [
{
icon: "check",
label: "Publish this note",
value: "publish"
},
{
icon: "clear",
label: "Skip this note",
value: "skip"
},
{
icon: "open_in_new",
label: 'Let me see it first. Ctrl-O, then type "Resume webnotes" to resume the process',
value: "open"
}
]
}
);
if (console.log("userAction", userAction), console.log("optionDoTheSameForAllRemainingNotes", optionDoTheSameForAllRemainingNotes), action = userAction, action === "open") {
console.log("navigating to note", noteDetails.name), await app.navigate(`https://www.amplenote.com/notes/${noteDetails.uuid}`), await this.waitForResume();
continue;
}
optionDoTheSameForAllRemainingNotes && (optionConfirmEveryNote = !1, actionToTakeForAllRemainingNotes = action);
break;
}
if (action === "publish" || !optionConfirmEveryNote && !actionToTakeForAllRemainingNotes)
console.log("publishing note", note), await app.publishNote(note);
else if (action === "skip") {
console.log("skipping note", note);
continue;
}
}
},
async waitForResume() {
return new Promise((resolve) => {
this.resumeResolver = resolve;
});
},
noteOption: {
"Publish this note and all its children": async function(app, noteUUID) {
let currentNote = await app.findNote({ uuid: noteUUID }), noteName = currentNote.name, [optionConfirmEveryNote, optionCreateHomepage] = await app.prompt(
`Publish "${noteName}" and all notes linked from it. All selected notes will become public.`,
{
inputs: [
{
type: "checkbox",
label: "Ask me to manually confirm each note before publishing"
},
{
type: "checkbox",
label: "Also create a homepage/index page, containing a list of links to all of the published notes"
}
]
}
);
console.log("currentNote", currentNote), console.log("optionConfirmEveryNote", optionConfirmEveryNote), console.log("optionCreateHomepage", optionCreateHomepage);
let noteList = [currentNote];
console.log("noteList", noteList);
let noteSources = new Map();
noteSources.set(currentNote.uuid, "\u{1F4DD} Root note");
let linkedNotesWithSources = await this.getLinkedNotesFromManyNotes(app, noteList);
console.log("linkedNotes", linkedNotesWithSources);
for (let { note, source } of linkedNotesWithSources)
noteList.push(note), noteSources.set(note.uuid, `\u{1F4D2} Linked from ${source}`);
if (optionCreateHomepage) {
let homepageNote = await this.createHomepageNote(app, `"${noteName}" Collection`, noteList);
console.log("homepageNote", homepageNote), noteList.push(homepageNote), noteSources.set(homepageNote.uuid, "\u{1F3E0} Homepage");
}
let answer = await app.prompt("Let's double check the list of notes to be published. Uncheck any notes you don't want to publish.", {
inputs: noteList.map((note) => ({
type: "checkbox",
label: `${note.name} (${noteSources.get(note.uuid)})`,
value: !0
}))
});
if (console.log("answer", answer), noteList = noteList.filter((note, index) => answer[index]), console.log("noteList", noteList), optionCreateHomepage) {
let homepageNote = noteList.find((note) => noteSources.get(note.uuid) === "\u{1F3E0} Homepage");
homepageNote && await this.insertHomepageContent(app, homepageNote, `"${noteName}" Collection`, noteList.filter((note) => noteSources.get(note.uuid) !== "\u{1F3E0} Homepage"));
}
await this.publishNotes(app, noteList, optionConfirmEveryNote);
}
},
insertText: {
"Insert embed at current position": async function(app, noteUUID) {
let currentNote = await app.findNote({ uuid: noteUUID }), results = await app.prompt("Insert the embed code/iframe you want to insert", {
inputs: [
{
type: "text",
label: "Embed code/iframe"
}
]
});
console.log("results", results);
let width = results.match(/width="(\d+)"/), height = results.match(/height="(\d+)"/), ratio = results.match(/ratio="(\d+):(\d+)"/), aspectRatio;
width && height ? aspectRatio = parseInt(width[1]) / parseInt(height[1]) : ratio ? aspectRatio = parseInt(ratio[1]) / parseInt(ratio[2]) : aspectRatio = 16 / 9, console.log("aspectRatio", aspectRatio);
let encodedResults = encodeURIComponent(results);
await app.context.replaceSelection(`<object data="plugin://${app.context.pluginUUID}?${encodedResults}" data-aspect-ratio="${aspectRatio}"/>`);
}
},
validateSettings(app, settings) {
let autoPublish = settings["Auto-publish new notes linked to from public notes"];
if (autoPublish !== "Yes" && autoPublish !== "No" && autoPublish !== "yes" && autoPublish !== "no")
return ['Enter "yes" or "no" without the quotes in this field'];
},
async onNoteCreated(app, noteHandle) {
if (app.settings["Auto-publish new notes linked to from public notes"] !== "yes" && app.settings["Auto-publish new notes linked to from public notes"] !== "Yes")
return;
console.log("onNoteCreated", noteHandle), await new Promise((resolve) => setTimeout(resolve, 1e3));
let backlinks = await app.getNoteBacklinks(noteHandle);
console.log("backlinks", backlinks);
let foundPublicNote = !1;
for (let backlink of backlinks) {
let backlinkNote = await app.findNote({ uuid: backlink.uuid }), publicURL = await app.getNotePublicURL(backlinkNote);
if (console.log("publicURL", publicURL), publicURL) {
foundPublicNote = !0;
break;
}
}
foundPublicNote && (console.log(`Note ${noteHandle.name} is linked to from a public note, so it will be published to the web.`), this.publishNotes(app, [noteHandle], !1));
},
renderEmbed(app, iframeHTML) {
let decodedHTML = decodeURIComponent(iframeHTML);
return decodedHTML.includes("<iframe") && (decodedHTML = this.makeIframeResponsive(decodedHTML)), decodedHTML;
},
makeIframeResponsive(iframeHTML) {
let iframeMatch = iframeHTML.match(/<iframe[^>]*>/i);
if (!iframeMatch) return iframeHTML;
let iframe = iframeMatch[0], srcMatch = iframe.match(/src="([^"]+)"/i);
if (!srcMatch) return iframeHTML;
let src = srcMatch[1], paddingBottom = (1 / this.getAspectRatioForEmbed(src, iframe) * 100).toFixed(2), attributes = this.extractIframeAttributes(iframe);
return `
<div style="position: relative; width: 100%; height: 0; padding-bottom: ${paddingBottom}%;">
<iframe
src="${src}"
title="${attributes.title}"
frameborder="0"
${attributes.allow ? `allow="${attributes.allow}"` : ""}
${attributes.referrerpolicy ? `referrerpolicy="${attributes.referrerpolicy}"` : ""}
${attributes.allowfullscreen ? "allowfullscreen" : ""}
${attributes.loading ? `loading="${attributes.loading}"` : ""}
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; ${attributes.style || ""}"
${attributes.otherAttrs}>
</iframe>
</div>
`;
},
getAspectRatioForEmbed(src, iframe) {
let widthMatch = iframe.match(/width="(\d+)"/i), heightMatch = iframe.match(/height="(\d+)"/i);
if (widthMatch && heightMatch) {
let width = parseInt(widthMatch[1]), height = parseInt(heightMatch[1]);
return width / height;
}
return 16 / 9;
},
extractIframeAttributes(iframe) {
let attributes = {
title: this.extractAttribute(iframe, "title") || "Embedded content",
allow: this.extractAttribute(iframe, "allow"),
referrerpolicy: this.extractAttribute(iframe, "referrerpolicy"),
loading: this.extractAttribute(iframe, "loading"),
style: this.extractAttribute(iframe, "style"),
allowfullscreen: iframe.toLowerCase().includes("allowfullscreen"),
otherAttrs: ""
}, knownAttrs = ["src", "width", "height", "title", "allow", "referrerpolicy", "loading", "style", "frameborder", "allowfullscreen"], otherAttrs = (iframe.match(/(\w+)="[^"]*"/g) || []).filter((attr) => !knownAttrs.some((known) => attr.toLowerCase().startsWith(known.toLowerCase()))).join(" ");
return attributes.otherAttrs = otherAttrs, attributes;
},
extractAttribute(iframe, attrName) {
let match = iframe.match(new RegExp(`${attrName}="([^"]+)"`, "i"));
return match ? match[1] : null;
},
onEmbedCall: createOnEmbedCallHandler(COMMON_EMBED_COMMANDS)
}, plugin_default = plugin;
return plugin;
})()