Skip to content

Commit f4f293a

Browse files
committed
main: add polyfill for old Supernote Webview
`.at` is missing from the Supernote webview. Polyfill it. This took me awhile to figure out because the types that need the polyfill aren't just the Array object. I am not a JS expert. Fixes #43
1 parent a397621 commit f4f293a

File tree

6 files changed

+69
-11
lines changed

6 files changed

+69
-11
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,11 @@ npm link supernote-typescript/
9090

9191
- `npm i` or `yarn` to install dependencies.
9292
- `npm run dev` to start compilation in watch mode.
93+
94+
**Android Debugging**
95+
96+
- Ensure `npm run dev` is running above
97+
- Create a vault called "SupernoteTest"
98+
- Install the supernote plugin from the community store
99+
- Run `npm run push-android` to push main.js to the device
100+
- Run "Reload App without Saving" on Obsidian command palette

package-lock.json

Lines changed: 16 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66
"scripts": {
77
"dev": "node esbuild.config.mjs",
88
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
9-
"version": "node version-bump.mjs && git add manifest.json versions.json"
9+
"version": "node version-bump.mjs && git add manifest.json versions.json",
10+
"push-android": "adb push main.js /sdcard/Documents/SupernoteTest/.obsidian/plugins/supernote"
1011
},
1112
"keywords": [],
1213
"author": "",
1314
"license": "MIT",
1415
"devDependencies": {
1516
"@types/color": "^3.0.6",
1617
"@types/jest": "^29.5.12",
17-
"@types/node": "^16.11.6",
18+
"@types/node": "^20.0.0",
1819
"@typescript-eslint/eslint-plugin": "5.29.0",
1920
"@typescript-eslint/parser": "5.29.0",
2021
"builtin-modules": "3.3.0",

src/main.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { installAtPolyfill } from './polyfills';
12
import { App, Modal, TFile, Plugin, Editor, MarkdownView, WorkspaceLeaf, FileView } from 'obsidian';
23
import { SupernotePluginSettings, SupernoteSettingTab, DEFAULT_SETTINGS } from './settings';
34
import { SupernoteX, fetchMirrorFrame } from 'supernote-typescript';
@@ -386,6 +387,9 @@ export default class SupernotePlugin extends Plugin {
386387
settings: SupernotePluginSettings;
387388

388389
async onload() {
390+
// Install polyfills before any other code runs
391+
installAtPolyfill();
392+
389393
await this.loadSettings();
390394
vw = new VaultWriter(this.app, this.settings);
391395

@@ -607,4 +611,4 @@ class ErrorModal extends Modal {
607611
const { contentEl } = this;
608612
contentEl.empty();
609613
}
610-
}
614+
}

src/myworker.worker.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import { installAtPolyfill } from 'polyfills';
2+
installAtPolyfill();
3+
14
import { SupernoteX, toImage } from 'supernote-typescript';
2-
import { Image } from 'image-js'
35

4-
export {};
6+
export { };
57

68
export type SupernoteWorkerMessage = {
79
type: 'convert';
@@ -42,4 +44,4 @@ self.onmessage = async (e: MessageEvent<SupernoteWorkerMessage>) => {
4244
error: error instanceof Error ? error.message : 'Unknown error occurred'
4345
});
4446
}
45-
};
47+
};

src/polyfills.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Polyfill for Array.prototype.at and TypedArray.prototype.at.
2+
// This is necessary for SuperNote devices with old WebView versions.
3+
export function installAtPolyfill() {
4+
if (!Array.prototype.at) {
5+
const at = function(n: number) {
6+
// ToInteger() abstract op
7+
n = Math.trunc(n) || 0;
8+
// Allow negative indexing from the end
9+
if (n < 0) n += this.length;
10+
// OOB access is guaranteed to return undefined
11+
if (n < 0 || n >= this.length) return undefined;
12+
// Otherwise, this is just normal property access
13+
return this[n];
14+
};
15+
16+
// Apply to Array and all TypedArray prototypes
17+
const typedArrays = [
18+
Int8Array, Uint8Array, Uint8ClampedArray,
19+
Int16Array, Uint16Array,
20+
Int32Array, Uint32Array,
21+
Float32Array, Float64Array,
22+
BigInt64Array, BigUint64Array
23+
];
24+
25+
Array.prototype.at = at;
26+
typedArrays.forEach(TypedArray => {
27+
if (TypedArray) {
28+
TypedArray.prototype.at = at;
29+
}
30+
});
31+
}
32+
}

0 commit comments

Comments
 (0)