Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.2.1] - 2026-07-28

Compliance fixes raised by Obsidian's plugin review. No change in behaviour.

### Fixed

- Elements are created through Obsidian's `createEl` helper instead of
`document.createElement`, per the plugin guidelines
(`obsidianmd/prefer-create-el`).
- The inert footnote marker's dotted underline is written with the
`text-decoration-line` / `text-decoration-style` longhands. Obsidian's CSS
check flags the multi-value `text-decoration` shorthand as only partially
supported at this plugin's `minAppVersion`.

### Internal — recurrence prevention

- `eslint-plugin-obsidianmd` moves 0.3.0 → 0.4.1. Both findings above are rules
the local gate already had in principle, but the pinned 0.3.0 did not yet
carry them, so CI could not have caught either one before submission.
- `npm run lint` now runs with `--max-warnings=0`. `prefer-create-el` reports at
*warning* severity, so the gate exited 0 while the violation stood; warnings
now fail the build the same as errors.

## [1.2.0] - 2026-07-28

### Added
Expand Down Expand Up @@ -192,7 +215,8 @@ Initial public release.
mode), not only in Reading view. The table being actively edited is left
untouched.

[Unreleased]: https://github.com/Post-Math/Lookout/compare/1.2.0...HEAD
[Unreleased]: https://github.com/Post-Math/Lookout/compare/1.2.1...HEAD
[1.2.1]: https://github.com/Post-Math/Lookout/compare/1.2.0...1.2.1
[1.2.0]: https://github.com/Post-Math/Lookout/compare/1.1.7...1.2.0
[#28]: https://github.com/Post-Math/Lookout/issues/28
[1.1.3]: https://github.com/Post-Math/Lookout/compare/1.1.2...1.1.3
Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "lookout",
"name": "Lookout",
"version": "1.2.0",
"version": "1.2.1",
"minAppVersion": "1.6.6",
"description": "Survey wide content instead of scrolling sideways. Pan and zoom Mermaid diagrams (wheel, Ctrl+wheel, or buttons), fit them to the frame, and open diagrams or wide tables full-screen.",
"author": "Post-Math",
Expand Down
43 changes: 37 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"dev": "node esbuild.config.mjs",
"build": "tsc --noEmit --skipLibCheck && node esbuild.config.mjs production",
"typecheck": "tsc --noEmit --skipLibCheck",
"lint": "eslint \"src/**/*.ts\"",
"lint": "eslint --max-warnings=0 \"src/**/*.ts\"",
"validate": "node scripts/validate.mjs",
"test:e2e": "npm run test:e2e:table && npm run test:e2e:diagram",
"test:e2e:table": "node tests/e2e/table-fullscreen.test.mjs",
Expand All @@ -27,7 +27,7 @@
"@types/node": "^20.14.0",
"esbuild": "^0.25.0",
"eslint": "^9.39.4",
"eslint-plugin-obsidianmd": "^0.3.0",
"eslint-plugin-obsidianmd": "^0.4.1",
"obsidian": "^1.6.0",
"playwright-core": "^1.48.0",
"tslib": "^2.6.0",
Expand Down
12 changes: 8 additions & 4 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,18 @@ function svgIcon(name: IconName): SVGSVGElement {
return svg;
}

/** Create an element with an optional class. Tag-typed so callers keep `.type`, `.disabled`, … */
/**
* Create a detached element with an optional class. Tag-typed so callers keep
* `.type`, `.disabled`, … Obsidian's `createEl` rather than
* `document.createElement`, per its plugin guidelines: `Node.createEl` would
* *append* to the node it is called on, so the free function is the one that
* returns something detached.
*/
function el<K extends keyof HTMLElementTagNameMap>(
tag: K,
cls?: string
): HTMLElementTagNameMap[K] {
const node = activeDocument.createElement(tag);
if (cls) node.className = cls;
return node;
return createEl(tag, cls ? { cls } : undefined);
}

/** Clamp `v` into the inclusive `[lo, hi]` range. */
Expand Down
6 changes: 5 additions & 1 deletion styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,11 @@
.lookout-table-fs-scroll .lookout-fn-unresolved {
color: var(--text-muted);
cursor: default;
text-decoration: underline dotted;
/* Longhands, not the `text-decoration` shorthand: Obsidian's plugin CSS check
flags the multi-value shorthand as only partially supported at our
`minAppVersion`, while these two have been safe for far longer. */
text-decoration-line: underline;
text-decoration-style: dotted;
text-underline-offset: 2px;
}

Expand Down
22 changes: 22 additions & 0 deletions tests/e2e/diagram-fit.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@ const bootstrap = `
// Obsidian runtime augmentations the bundle relies on (absent outside Obsidian).
globalThis.activeWindow = window;
globalThis.activeDocument = document;
// Obsidian's DOM helper, faithful to the real signature: the second argument
// is a class string or a DomElementInfo. A stub shaped to whatever the code
// happens to ask for is how a green suite hid a broken feature before.
globalThis.createEl = function (tag, o, cb) {
const node = document.createElement(tag);
if (typeof o === "string") o = { cls: o };
if (o) {
if (o.cls) node.className = Array.isArray(o.cls) ? o.cls.join(" ") : o.cls;
if (o.text) node.textContent = o.text;
if (o.attr) for (const k in o.attr) node.setAttribute(k, o.attr[k]);
if (o.title) node.title = o.title;
if (o.parent) o.prepend ? o.parent.prepend(node) : o.parent.appendChild(node);
}
if (cb) cb(node);
return node;
};
Node.prototype.createEl = function (tag, o, cb) {
if (typeof o === "string") o = { cls: o };
o = o || {};
o.parent = this;
return globalThis.createEl(tag, o, cb);
};
const _setCssStyles = function (styles) { Object.assign(this.style, styles); };
const _setCssProps = function (props) { for (const k in props) this.style.setProperty(k, props[k]); };
HTMLElement.prototype.setCssStyles = _setCssStyles;
Expand Down
22 changes: 22 additions & 0 deletions tests/e2e/table-fullscreen.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,28 @@ const bootstrap = `
// Obsidian runtime augmentations the bundle relies on (absent outside Obsidian).
globalThis.activeWindow = window;
globalThis.activeDocument = document;
// Obsidian's DOM helper, faithful to the real signature: the second argument
// is a class string or a DomElementInfo. A stub shaped to whatever the code
// happens to ask for is how a green suite hid a broken feature before.
globalThis.createEl = function (tag, o, cb) {
const node = document.createElement(tag);
if (typeof o === "string") o = { cls: o };
if (o) {
if (o.cls) node.className = Array.isArray(o.cls) ? o.cls.join(" ") : o.cls;
if (o.text) node.textContent = o.text;
if (o.attr) for (const k in o.attr) node.setAttribute(k, o.attr[k]);
if (o.title) node.title = o.title;
if (o.parent) o.prepend ? o.parent.prepend(node) : o.parent.appendChild(node);
}
if (cb) cb(node);
return node;
};
Node.prototype.createEl = function (tag, o, cb) {
if (typeof o === "string") o = { cls: o };
o = o || {};
o.parent = this;
return globalThis.createEl(tag, o, cb);
};
const _setCssStyles = function (styles) { Object.assign(this.style, styles); };
const _setCssProps = function (props) { for (const k in props) this.style.setProperty(k, props[k]); };
HTMLElement.prototype.setCssStyles = _setCssStyles;
Expand Down
3 changes: 2 additions & 1 deletion versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"1.1.5": "1.0.0",
"1.1.6": "1.0.0",
"1.1.7": "1.0.0",
"1.2.0": "1.6.6"
"1.2.0": "1.6.6",
"1.2.1": "1.6.6"
}