Live Preview is done

This commit is contained in:
Luis Alberto Jaramillo Gonzalez 2024-01-22 10:34:10 -05:00
parent acbb6c0d1e
commit 67e2d652f2
No known key found for this signature in database
GPG key ID: 0444CB0073EDFBB5
6 changed files with 164 additions and 12 deletions

View file

@ -2,6 +2,7 @@ import { GpgSettingsTab } from 'src/SettingsTab';
import { HotKeys } from 'src/HotKeys';
import { Plugin } from 'obsidian';
import { GpgEncryptSettings, Settings } from 'src/Settings';
import { livePreviewExtensionGpgEncrypt } from 'src/LivePreview';
// My plugin PGP Encrypt
export default class GpgEncryptPlugin extends Plugin {
@ -19,6 +20,8 @@ export default class GpgEncryptPlugin extends Plugin {
let hotKeys: HotKeys = new HotKeys(this.app, this);
this.addCommand(hotKeys.GpgEncryptInline);
this.addCommand(hotKeys.GpgEncryptDocument);
// Add Live Privew Extension GPG Encrypt
this.registerEditorExtension(livePreviewExtensionGpgEncrypt(this.app));
}
// OnUnload Method in PGP Encrypt Plugin

51
package-lock.json generated
View file

@ -8,6 +8,9 @@
"name": "obsidian-sample-plugin",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"@codemirror/language": "^6.10.0"
},
"devDependencies": {
"@types/node": "^16.11.6",
"@typescript-eslint/eslint-plugin": "5.29.0",
@ -29,19 +32,28 @@
"node": ">=0.10.0"
}
},
"node_modules/@codemirror/language": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.0.tgz",
"integrity": "sha512-2vaNn9aPGCRFKWcHPFksctzJ8yS5p7YoaT+jHpc0UGKzNuAIx4qy6R5wiqbP+heEEdyaABA582mNqSHzSoYdmg==",
"dependencies": {
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.23.0",
"@lezer/common": "^1.1.0",
"@lezer/highlight": "^1.0.0",
"@lezer/lr": "^1.0.0",
"style-mod": "^4.0.0"
}
},
"node_modules/@codemirror/state": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.0.tgz",
"integrity": "sha512-hm8XshYj5Fo30Bb922QX9hXB/bxOAVH+qaqHBzw5TKa72vOeslyGwd4X8M0c1dJ9JqxlaMceOQ8RsL9tC7gU0A==",
"dev": true,
"peer": true
"integrity": "sha512-hm8XshYj5Fo30Bb922QX9hXB/bxOAVH+qaqHBzw5TKa72vOeslyGwd4X8M0c1dJ9JqxlaMceOQ8RsL9tC7gU0A=="
},
"node_modules/@codemirror/view": {
"version": "6.23.0",
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.23.0.tgz",
"integrity": "sha512-/51px9N4uW8NpuWkyUX+iam5+PM6io2fm+QmRnzwqBy5v/pwGg9T0kILFtYeum8hjuvENtgsGNKluOfqIICmeQ==",
"dev": true,
"peer": true,
"dependencies": {
"@codemirror/state": "^6.4.0",
"style-mod": "^4.1.0",
@ -496,6 +508,27 @@
"dev": true,
"peer": true
},
"node_modules/@lezer/common": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
"integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ=="
},
"node_modules/@lezer/highlight": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
"integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
"dependencies": {
"@lezer/common": "^1.0.0"
}
},
"node_modules/@lezer/lr": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.0.tgz",
"integrity": "sha512-Wst46p51km8gH0ZUmeNrtpRYmdlRHUpN1DQd3GFAyKANi8WVz8c2jHYTf1CVScFaCjQw1iO3ZZdqGDxQPRErTg==",
"dependencies": {
"@lezer/common": "^1.0.0"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -2064,9 +2097,7 @@
"node_modules/style-mod": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.0.tgz",
"integrity": "sha512-Ca5ib8HrFn+f+0n4N4ScTIA9iTOQ7MaGS1ylHcoVqW9J7w2w8PzN6g9gKmTYgGEBH8e120+RCmhpje6jC5uGWA==",
"dev": true,
"peer": true
"integrity": "sha512-Ca5ib8HrFn+f+0n4N4ScTIA9iTOQ7MaGS1ylHcoVqW9J7w2w8PzN6g9gKmTYgGEBH8e120+RCmhpje6jC5uGWA=="
},
"node_modules/supports-color": {
"version": "7.2.0",
@ -2179,9 +2210,7 @@
"node_modules/w3c-keyname": {
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
"dev": true,
"peer": true
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
},
"node_modules/which": {
"version": "2.0.2",

View file

@ -20,5 +20,8 @@
"obsidian": "latest",
"tslib": "2.4.0",
"typescript": "4.7.4"
},
"dependencies": {
"@codemirror/language": "^6.10.0"
}
}

View file

@ -8,6 +8,9 @@ export enum EncryptModalMode {
DOCUMENT = "Document"
}
// GPG Encrypt Inline Prefix
export const GPG_INLINE_ENCRYPT_PREFIX: string = "gpg-base-64";
// Encrypt modal (Works for inline and document encryption)
export class EncryptModal extends Modal {
@ -152,6 +155,6 @@ export class EncryptModal extends Modal {
// Convert Buffer to text in Base64 with some scape characters to be identify in LivePreview
private BufferToSecretBase64(bufferEncrypted: Buffer): string {
// Return buffer converted in Base64 with some scape characters to be identify in LivePreview
return "`gpg-base-64 " + bufferEncrypted.toString('base64') + "`";
return "`" + GPG_INLINE_ENCRYPT_PREFIX + " " + bufferEncrypted.toString('base64') + "`";
}
}

View file

@ -0,0 +1,96 @@
import { EditorView, ViewPlugin, ViewUpdate, Decoration, DecorationSet, WidgetType } from '@codemirror/view';
import { GPG_INLINE_ENCRYPT_PREFIX } from "./EncryptModal";
import { App, editorLivePreviewField } from "obsidian";
import type { PluginValue, } from '@codemirror/view';
import { RangeSetBuilder } from '@codemirror/state';
import { syntaxTree } from "@codemirror/language";
// widget that will replace the encrypted text
export class EncryptedWidget extends WidgetType {
// Constructor function with initial args
constructor(public app: App, public value: string) {
super();
}
// Method that will manipulate DOM to include decrypt button
toDOM(view: EditorView): HTMLElement {
// New div that will contain the decrypt button
const div = document.createElement("span");
// Add new CSS class to div
div.addClass('gpg-decrypt-div');
// New div that is the decrypt button
let a = div.createEl('a');
// Add new CSS class to a
a.addClass('gpg-decrypt-a');
// OnClickEvent in element a
a.onClickEvent((event: MouseEvent) => {
//this.app, event, this.value
// TODO: Call Decrypt Modal
});
// Return div that contains decrypt button
return div;
}
}
// Live Preview Extension to change encrypted text into a image button
export const livePreviewExtensionGpgEncrypt = (app: App) => ViewPlugin.fromClass(class implements PluginValue {
// Decoration set
decorations: DecorationSet;
// Constructor to inicialize EditorView
constructor(view: EditorView) {
this.decorations = this.buildDecorations(view);
}
// Update function
update(update: ViewUpdate) {
if (!update.state.field(editorLivePreviewField)) {
this.decorations = Decoration.none;
return;
}
if (update.docChanged || update.viewportChanged || update.selectionSet) {
this.decorations = this.buildDecorations(update.view);
}
}
// Function to build decorations
private buildDecorations(view: EditorView): DecorationSet {
// In case of editor is not in Live Preview
if (!view.state.field(editorLivePreviewField)) {
// Return that decoration is none
return Decoration.none;
}
// Creatin instance of builder
const builder = new RangeSetBuilder<Decoration>();
// Iterate over each visible ranges
for (const { from, to } of view.visibleRanges) {
// Iterate over each state
syntaxTree(view.state).iterate({ from, to, enter(node: any) {
// Check if type of line is a inline-code
if (node.type.name.startsWith("inline-code")) {
// Get value of this inline-code
const value = view.state.doc.sliceString(node.from, node.to)
// Check if this line start with GPG Inline Encrypt Prefix and mark isEncrypted as true
const isEncrypted = value.indexOf(GPG_INLINE_ENCRYPT_PREFIX) === 0;
// Check if isEncrypted is true
if (isEncrypted) {
// Replace the decoration for EncryptedWidget
builder.add(node.from, node.to,
Decoration.replace({
widget: new EncryptedWidget(app, value)
})
);
}
}
}});
}
return builder.finish();
}
// Destry method
destroy() {
}
},
{ decorations: instance => instance.decorations });

View file

@ -9,4 +9,22 @@
}
.div-spacer {
height: 20px;
}
.gpg-decrypt-div {
display: inline-block;
vertical-align: middle;
}
.gpg-decrypt-a {
background-color: var(--text-faint);
mask-image: url('data:image/svg+xml,<svg width="360" height="60" version="1.1" viewBox="0 0 95.25 15.875" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-67.168 -52.917)"><g stroke-width=".22324" aria-label="SECRET"><path d="m95.294 68.262q-2.0574 0-3.2766-1.0668-1.2192-1.0858-1.2192-2.9718h1.8859q0 1.1049 0.70485 1.7336t1.905 0.62865q1.143 0 1.8098-0.62865 0.6858-0.6477 0.6858-1.7145 0-0.8001-0.43815-1.3906-0.43815-0.6096-1.2382-0.81915l-2.0574-0.55245q-1.3526-0.381-2.1526-1.3716-0.78105-1.0096-0.78105-2.3812 0-1.124 0.4953-1.9622 0.51435-0.85725 1.4287-1.3144 0.9144-0.47625 2.1146-0.47625 1.2192 0 2.1336 0.47625 0.93345 0.4572 1.4478 1.2954t0.51435 1.9431h-1.8669q0-0.9144-0.62865-1.4859-0.6096-0.5715-1.6002-0.5715t-1.6002 0.5715q-0.59055 0.5715-0.59055 1.4859 0 0.74295 0.40005 1.2573 0.40005 0.4953 1.124 0.70485l2.1146 0.5715q1.4288 0.381 2.2288 1.4668 0.8001 1.0668 0.8001 2.5527 0 1.2192-0.5334 2.1336-0.5334 0.89535-1.524 1.3906-0.97155 0.4953-2.286 0.4953z"/><path d="m102.78 68.072v-13.906h8.0962v1.6954h-6.2293v4.1338h5.5626v1.6383h-5.5626v4.7434h6.2293v1.6954z"/><path d="m118.23 68.262q-1.924 0-3.067-1.0668-1.124-1.0858-1.124-2.9718v-6.2294q0-1.8669 1.124-2.9337 1.143-1.0858 3.067-1.0858 1.905 0 3.029 1.0858 1.143 1.0858 1.143 2.9337h-1.886q0-1.124-0.6096-1.7336t-1.6764-0.6096q-1.0858 0-1.6954 0.6096t-0.6096 1.7336v6.2294q0 1.143 0.6096 1.7526t1.6954 0.6096q1.0668 0 1.6764-0.6096t0.6096-1.7526h1.886q0 1.8669-1.143 2.9528-1.124 1.0858-3.029 1.0858z"/><path d="m125.49 68.072v-13.906h4.3053q1.2764 0 2.2288 0.51435 0.9525 0.4953 1.4859 1.4097 0.5334 0.89535 0.5334 2.1146 0 1.4097-0.7239 2.4194-0.70485 1.0096-1.886 1.4288l2.8004 6.0198h-2.0764l-2.648-5.8102h-2.1526v5.8102zm1.8669-7.4866h2.4384q1.0668 0 1.6764-0.6477 0.62865-0.6477 0.62865-1.7145 0-1.0858-0.62865-1.7336t-1.6764-0.6477h-2.4384z"/><path d="m137.07 68.072v-13.906h8.0962v1.6954h-6.2294v4.1338h5.5626v1.6383h-5.5626v4.7434h6.2294v1.6954z"/><path d="m151.43 68.072v-12.192h-3.7719v-1.7145h9.4107v1.7145h-3.7528v12.192z"/></g><g id="XMLID_509_" transform="matrix(.057518 0 0 .048106 70.113 52.917)"><path id="XMLID_510_" d="m65 330h200c8.284 0 15-6.716 15-15v-170c0-8.284-6.716-15-15-15h-15v-45c0-46.869-38.131-85-85-85s-85 38.131-85 85v45h-15c-8.284 0-15 6.716-15 15v170c0 8.284 6.716 15 15 15zm115-95.014v20.014c0 8.284-6.716 15-15 15s-15-6.716-15-15v-20.014c-6.068-4.565-10-11.824-10-19.986 0-13.785 11.215-25 25-25s25 11.215 25 25c0 8.162-3.932 15.421-10 19.986zm-70-149.99c0-30.327 24.673-55 55-55s55 24.673 55 55v45h-110z"/></g></g></svg>');
-webkit-mask-image: url('data:image/svg+xml,<svg width="360" height="60" version="1.1" viewBox="0 0 95.25 15.875" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-67.168 -52.917)"><g stroke-width=".22324" aria-label="SECRET"><path d="m95.294 68.262q-2.0574 0-3.2766-1.0668-1.2192-1.0858-1.2192-2.9718h1.8859q0 1.1049 0.70485 1.7336t1.905 0.62865q1.143 0 1.8098-0.62865 0.6858-0.6477 0.6858-1.7145 0-0.8001-0.43815-1.3906-0.43815-0.6096-1.2382-0.81915l-2.0574-0.55245q-1.3526-0.381-2.1526-1.3716-0.78105-1.0096-0.78105-2.3812 0-1.124 0.4953-1.9622 0.51435-0.85725 1.4287-1.3144 0.9144-0.47625 2.1146-0.47625 1.2192 0 2.1336 0.47625 0.93345 0.4572 1.4478 1.2954t0.51435 1.9431h-1.8669q0-0.9144-0.62865-1.4859-0.6096-0.5715-1.6002-0.5715t-1.6002 0.5715q-0.59055 0.5715-0.59055 1.4859 0 0.74295 0.40005 1.2573 0.40005 0.4953 1.124 0.70485l2.1146 0.5715q1.4288 0.381 2.2288 1.4668 0.8001 1.0668 0.8001 2.5527 0 1.2192-0.5334 2.1336-0.5334 0.89535-1.524 1.3906-0.97155 0.4953-2.286 0.4953z"/><path d="m102.78 68.072v-13.906h8.0962v1.6954h-6.2293v4.1338h5.5626v1.6383h-5.5626v4.7434h6.2293v1.6954z"/><path d="m118.23 68.262q-1.924 0-3.067-1.0668-1.124-1.0858-1.124-2.9718v-6.2294q0-1.8669 1.124-2.9337 1.143-1.0858 3.067-1.0858 1.905 0 3.029 1.0858 1.143 1.0858 1.143 2.9337h-1.886q0-1.124-0.6096-1.7336t-1.6764-0.6096q-1.0858 0-1.6954 0.6096t-0.6096 1.7336v6.2294q0 1.143 0.6096 1.7526t1.6954 0.6096q1.0668 0 1.6764-0.6096t0.6096-1.7526h1.886q0 1.8669-1.143 2.9528-1.124 1.0858-3.029 1.0858z"/><path d="m125.49 68.072v-13.906h4.3053q1.2764 0 2.2288 0.51435 0.9525 0.4953 1.4859 1.4097 0.5334 0.89535 0.5334 2.1146 0 1.4097-0.7239 2.4194-0.70485 1.0096-1.886 1.4288l2.8004 6.0198h-2.0764l-2.648-5.8102h-2.1526v5.8102zm1.8669-7.4866h2.4384q1.0668 0 1.6764-0.6477 0.62865-0.6477 0.62865-1.7145 0-1.0858-0.62865-1.7336t-1.6764-0.6477h-2.4384z"/><path d="m137.07 68.072v-13.906h8.0962v1.6954h-6.2294v4.1338h5.5626v1.6383h-5.5626v4.7434h6.2294v1.6954z"/><path d="m151.43 68.072v-12.192h-3.7719v-1.7145h9.4107v1.7145h-3.7528v12.192z"/></g><g id="XMLID_509_" transform="matrix(.057518 0 0 .048106 70.113 52.917)"><path id="XMLID_510_" d="m65 330h200c8.284 0 15-6.716 15-15v-170c0-8.284-6.716-15-15-15h-15v-45c0-46.869-38.131-85-85-85s-85 38.131-85 85v45h-15c-8.284 0-15 6.716-15 15v170c0 8.284 6.716 15 15 15zm115-95.014v20.014c0 8.284-6.716 15-15 15s-15-6.716-15-15v-20.014c-6.068-4.565-10-11.824-10-19.986 0-13.785 11.215-25 25-25s25 11.215 25 25c0 8.162-3.932 15.421-10 19.986zm-70-149.99c0-30.327 24.673-55 55-55s55 24.673 55 55v45h-110z"/></g></g></svg>');
mask-size: contain;
-webkit-mask-size: contain;
display: inline-block;
width: 6em;
height: 1em;
vertical-align: text-top;
margin-left: 0px;
margin-top: 0px;
cursor: pointer;
}