Release OpenScript 1.0.3

This commit is contained in:
2026-09-12 22:14:22 -07:00
parent 3697048c6e
commit 1cd7b693ab
10 changed files with 155 additions and 13 deletions
+17 -5
View File
@@ -1,7 +1,7 @@
import {
getScripts, saveScripts, getSecrets, saveSecrets, garbageCollectScriptStorage,
} from './utils/storage.js';
import { parseMeta, getBoilerplate } from './utils/parser.js';
import { parseMeta, getBoilerplate, getMetaRunAt } from './utils/parser.js';
import { isUserScriptsAvailable } from './utils/userScripts.js';
import { renderIcons, icon } from './utils/icons.js';
import { VERSION } from './version.js';
@@ -44,6 +44,7 @@ const init = async () => {
state.scripts = scripts.map(s => ({
...s,
version: parseMeta(s.code || '').version,
runAt: getMetaRunAt(s.code || '') || s.runAt || 'document_idle',
}));
state.secrets = secrets;
render();
@@ -92,7 +93,7 @@ const saveCurrentScript = async () => {
requires: meta.requires,
requireCache: existing?.requireCache || {},
storageToken: existing?.storageToken,
runAt: $('#run-at-select')?.value || meta.runAt || 'document_idle',
runAt: getMetaRunAt(code) || $('#run-at-select')?.value || 'document_idle',
code,
enabled: existing ? existing.enabled : true,
updatedAt: Date.now(),
@@ -252,7 +253,7 @@ const renderScriptList = () => {
const renderEditor = () => {
const script = state.scripts.find(s => s.id === state.editingId);
const code = script ? script.code : getBoilerplate();
const runAt = script?.runAt || 'document_idle';
const runAt = getMetaRunAt(code) || script?.runAt || 'document_idle';
return `
<div class="flex flex-col flex-1 overflow-hidden bg-slate-50">
@@ -458,12 +459,23 @@ const bindEvents = () => {
$('#btn-cancel-edit')?.addEventListener('click', () => setTab('list'));
$('#btn-reset-boilerplate')?.addEventListener('click', () => {
const el = $('#editor-code');
if (el && confirm('Reset code to default boilerplate?')) el.value = getBoilerplate();
if (el && confirm('Reset code to default boilerplate?')) {
el.value = getBoilerplate();
const sel = $('#run-at-select');
const script = state.scripts.find(s => s.id === state.editingId);
if (sel) sel.value = script?.runAt || 'document_idle';
}
});
// Tab key indent in editor
// Tab key indent & metadata sync in editor
const textarea = $('#editor-code');
if (textarea) {
textarea.addEventListener('input', () => {
const metaRunAt = getMetaRunAt(textarea.value);
const sel = $('#run-at-select');
if (sel && metaRunAt) sel.value = metaRunAt;
});
textarea.addEventListener('keydown', e => {
if (e.key === 'Tab') {
e.preventDefault();
+7
View File
@@ -2,6 +2,13 @@
const SINGLE_KEYS = new Set(['name', 'version', 'description', 'run-at']);
const MULTI_KEYS = new Set(['match', 'require']);
const RUN_AT_OPTIONS = new Set(['document_start', 'document_end', 'document_idle']);
export const getMetaRunAt = code => {
const block = code.match(/\/\/ ==UserScript==([\s\S]*?)\/\/ ==\/UserScript==/)?.[1] || '';
const val = block.match(/\/\/\s*@run-at\s+([\w-]+)/i)?.[1]?.toLowerCase().replace('-', '_');
return RUN_AT_OPTIONS.has(val) ? val : null;
};
export const parseMeta = code => {
const block = code.match(/\/\/ ==UserScript==([\s\S]*?)\/\/ ==\/UserScript==/)?.[1] || '';
+4 -2
View File
@@ -1,5 +1,5 @@
import { getScripts, saveScripts, getSecrets } from './storage.js';
import { normalizeMatch, parseMeta } from './parser.js';
import { normalizeMatch, parseMeta, getMetaRunAt } from './parser.js';
import { VERSION } from '../version.js';
const STORAGE_MESSAGE = 'OPEN_SCRIPT_STORAGE';
@@ -91,14 +91,16 @@ export const syncUserScripts = async ({ refreshRequires = false } = {}) => {
scripts = scripts.map(script => {
const requires = parseMeta(script.code || '').requires;
const storageToken = script.storageToken || crypto.randomUUID();
const runAt = getMetaRunAt(script.code || '') || script.runAt || 'document_idle';
if (requires.some(url => script.requireCache?.[url] === undefined)) missingCache = true;
if (storageToken === script.storageToken &&
runAt === script.runAt &&
JSON.stringify(requires) === JSON.stringify(script.requires || [])) return script;
changed = true;
const requireCache = Object.fromEntries(requires.flatMap(url =>
script.requireCache && Object.hasOwn(script.requireCache, url) ? [[url, script.requireCache[url]]] : []
));
return { ...script, requires, requireCache, storageToken };
return { ...script, runAt, requires, requireCache, storageToken };
});
let warnings = [];
+1 -1
View File
@@ -1 +1 @@
export const VERSION = '1.0.2';
export const VERSION = '1.0.3';