tosijs-ui 1.6.6 → 1.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/code-editor.d.ts +6 -0
- package/dist/code-editor.js +43 -0
- package/dist/diff.d.ts +61 -0
- package/dist/diff.js +132 -0
- package/dist/doc-browser.d.ts +15 -1
- package/dist/doc-browser.js +355 -60
- package/dist/doc-system/doc-system-styles.js +4 -1
- package/dist/doc-system/doc-system.d.ts +5 -0
- package/dist/doc-system/doc-system.js +97 -7
- package/dist/doc-system/site/dev-server.js +56 -0
- package/dist/doc-system/site/generate-site.js +7 -0
- package/dist/doc-system/site/orchestrator.js +23 -8
- package/dist/doc-system/site/site-config.d.ts +7 -0
- package/dist/iife.js +84 -78
- package/dist/iife.js.map +17 -14
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/live-example/code-transform.d.ts +8 -5
- package/dist/live-example/code-transform.js +56 -31
- package/dist/live-example/component.d.ts +23 -1
- package/dist/live-example/component.js +291 -22
- package/dist/live-example/example-store.d.ts +12 -0
- package/dist/live-example/example-store.js +47 -0
- package/dist/live-example/insert-examples.d.ts +1 -1
- package/dist/live-example/insert-examples.js +18 -1
- package/dist/live-example/save-to-source.d.ts +23 -0
- package/dist/live-example/save-to-source.js +95 -0
- package/dist/live-example/styles.d.ts +5 -0
- package/dist/live-example/styles.js +8 -0
- package/dist/live-example/test-harness.js +2 -2
- package/dist/menu.js +14 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/llms.txt +3 -1
- package/package.json +4 -4
package/dist/code-editor.d.ts
CHANGED
|
@@ -4,6 +4,12 @@ export declare class CodeEditor extends WebComponent {
|
|
|
4
4
|
private source;
|
|
5
5
|
get value(): string;
|
|
6
6
|
set value(text: string);
|
|
7
|
+
private _original;
|
|
8
|
+
get original(): string;
|
|
9
|
+
set original(text: string);
|
|
10
|
+
private diffOverlay;
|
|
11
|
+
get showingDiff(): boolean;
|
|
12
|
+
showDiff(on: boolean): void;
|
|
7
13
|
static initAttributes: {
|
|
8
14
|
mode: string;
|
|
9
15
|
theme: string;
|
package/dist/code-editor.js
CHANGED
|
@@ -23,6 +23,7 @@ and an `ace` property that returns the `ace` module, giving you complete access
|
|
|
23
23
|
/*{ "parent": "Components" }*/
|
|
24
24
|
import { Component as WebComponent } from 'tosijs';
|
|
25
25
|
import { scriptTag } from './via-tag';
|
|
26
|
+
import { tosiDiff } from './diff';
|
|
26
27
|
const ACE_BASE_URL = 'https://cdnjs.cloudflare.com/ajax/libs/ace/1.23.2/';
|
|
27
28
|
const DEFAULT_THEME = 'ace/theme/tomorrow';
|
|
28
29
|
const getAce = async () => {
|
|
@@ -37,6 +38,10 @@ const makeCodeEditor = async (codeElement, mode = 'html', options = {}, theme =
|
|
|
37
38
|
tabSize: 2,
|
|
38
39
|
useSoftTabs: true,
|
|
39
40
|
useWorker: false,
|
|
41
|
+
// Wrap wide lines instead of scrolling horizontally; indentedSoftWrap keeps
|
|
42
|
+
// wrapped continuations aligned under the line's indent.
|
|
43
|
+
wrap: true,
|
|
44
|
+
indentedSoftWrap: true,
|
|
40
45
|
...options,
|
|
41
46
|
});
|
|
42
47
|
editor.setTheme(theme);
|
|
@@ -58,6 +63,44 @@ export class CodeEditor extends WebComponent {
|
|
|
58
63
|
this.editor.session.getUndoManager().reset();
|
|
59
64
|
}
|
|
60
65
|
}
|
|
66
|
+
// Baseline for `showDiff()` — the version to diff the current `value` against.
|
|
67
|
+
// Defaults to the current value (no diff) until a caller sets it.
|
|
68
|
+
_original;
|
|
69
|
+
get original() {
|
|
70
|
+
return this._original ?? this.value;
|
|
71
|
+
}
|
|
72
|
+
set original(text) {
|
|
73
|
+
this._original = text;
|
|
74
|
+
}
|
|
75
|
+
// Diff overlay — deliberately built only on the editor's public surface
|
|
76
|
+
// (`value` + `original`) and the tosi-diff component, never the underlying
|
|
77
|
+
// editor's API, so it survives a future Ace → CodeMirror swap untouched.
|
|
78
|
+
diffOverlay;
|
|
79
|
+
get showingDiff() {
|
|
80
|
+
return this.diffOverlay !== undefined && !this.diffOverlay.hidden;
|
|
81
|
+
}
|
|
82
|
+
showDiff(on) {
|
|
83
|
+
if (on) {
|
|
84
|
+
if (this.diffOverlay === undefined) {
|
|
85
|
+
this.diffOverlay = tosiDiff({
|
|
86
|
+
style: {
|
|
87
|
+
position: 'absolute',
|
|
88
|
+
inset: '0',
|
|
89
|
+
zIndex: '5',
|
|
90
|
+
overflow: 'auto',
|
|
91
|
+
background: 'var(--tosi-diff-bg, var(--background, #fff))',
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
this.append(this.diffOverlay);
|
|
95
|
+
}
|
|
96
|
+
this.diffOverlay.original = this.original;
|
|
97
|
+
this.diffOverlay.modified = this.value;
|
|
98
|
+
this.diffOverlay.hidden = false;
|
|
99
|
+
}
|
|
100
|
+
else if (this.diffOverlay !== undefined) {
|
|
101
|
+
this.diffOverlay.hidden = true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
61
104
|
static initAttributes = {
|
|
62
105
|
mode: 'javascript',
|
|
63
106
|
theme: DEFAULT_THEME,
|
package/dist/diff.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Component, ElementCreator, PartsMap } from 'tosijs';
|
|
2
|
+
export type DiffOp = 'context' | 'add' | 'remove';
|
|
3
|
+
export interface DiffLine {
|
|
4
|
+
op: DiffOp;
|
|
5
|
+
text: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Line-level diff of two strings via longest-common-subsequence, returning each
|
|
9
|
+
* line tagged `context` (unchanged), `remove` (only in `before`), or `add` (only
|
|
10
|
+
* in `after`), in display order.
|
|
11
|
+
*/
|
|
12
|
+
export declare function diffLines(before: string, after: string): DiffLine[];
|
|
13
|
+
interface DiffParts extends PartsMap {
|
|
14
|
+
body: HTMLElement;
|
|
15
|
+
}
|
|
16
|
+
export declare class TosiDiff extends Component<DiffParts> {
|
|
17
|
+
static preferredTagName: string;
|
|
18
|
+
static initAttributes: {
|
|
19
|
+
original: string;
|
|
20
|
+
modified: string;
|
|
21
|
+
};
|
|
22
|
+
static shadowStyleSpec: {
|
|
23
|
+
':host': {
|
|
24
|
+
display: string;
|
|
25
|
+
overflow: string;
|
|
26
|
+
font: string;
|
|
27
|
+
background: string;
|
|
28
|
+
color: string;
|
|
29
|
+
};
|
|
30
|
+
':host([hidden])': {
|
|
31
|
+
display: string;
|
|
32
|
+
};
|
|
33
|
+
'.diff-line': {
|
|
34
|
+
display: string;
|
|
35
|
+
gridTemplateColumns: string;
|
|
36
|
+
whiteSpace: string;
|
|
37
|
+
wordBreak: string;
|
|
38
|
+
};
|
|
39
|
+
'.diff-line .marker': {
|
|
40
|
+
textAlign: string;
|
|
41
|
+
userSelect: string;
|
|
42
|
+
opacity: string;
|
|
43
|
+
};
|
|
44
|
+
'.diff-add': {
|
|
45
|
+
background: string;
|
|
46
|
+
};
|
|
47
|
+
'.diff-add .marker': {
|
|
48
|
+
color: string;
|
|
49
|
+
};
|
|
50
|
+
'.diff-remove': {
|
|
51
|
+
background: string;
|
|
52
|
+
};
|
|
53
|
+
'.diff-remove .marker': {
|
|
54
|
+
color: string;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
content: () => HTMLDivElement[];
|
|
58
|
+
render(): void;
|
|
59
|
+
}
|
|
60
|
+
export declare const tosiDiff: ElementCreator<TosiDiff>;
|
|
61
|
+
export {};
|
package/dist/diff.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/*#
|
|
2
|
+
# diff
|
|
3
|
+
|
|
4
|
+
`<tosi-diff>` renders a unified, line-by-line diff between two strings — the kind
|
|
5
|
+
of view you'd see in a code review, with removed lines marked `-` and added
|
|
6
|
+
lines marked `+`.
|
|
7
|
+
|
|
8
|
+
Set its `original` and `modified` properties (or attributes) to the two versions
|
|
9
|
+
of the text; it recomputes and re-renders. (They're named `original`/`modified`
|
|
10
|
+
rather than `before`/`after` to avoid the native `Element.before()`/`after()`
|
|
11
|
+
methods.)
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
const { tosiDiff } = tosijsui
|
|
15
|
+
|
|
16
|
+
preview.append(
|
|
17
|
+
tosiDiff({
|
|
18
|
+
original: 'one\ntwo\nthree\nfour',
|
|
19
|
+
modified: 'one\nTWO\nthree\nfour\nfive',
|
|
20
|
+
style: { width: '100%', height: '100%' },
|
|
21
|
+
})
|
|
22
|
+
)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The diff is computed with a longest-common-subsequence pass over the lines, so
|
|
26
|
+
unchanged lines are shown as context and only genuine insertions/deletions are
|
|
27
|
+
highlighted. The pure `diffLines(before, after)` function is exported too, if you
|
|
28
|
+
just want the data.
|
|
29
|
+
*/
|
|
30
|
+
/*{ "parent": "Components" }*/
|
|
31
|
+
import { Component, elements } from 'tosijs';
|
|
32
|
+
const { div, span } = elements;
|
|
33
|
+
/**
|
|
34
|
+
* Line-level diff of two strings via longest-common-subsequence, returning each
|
|
35
|
+
* line tagged `context` (unchanged), `remove` (only in `before`), or `add` (only
|
|
36
|
+
* in `after`), in display order.
|
|
37
|
+
*/
|
|
38
|
+
export function diffLines(before, after) {
|
|
39
|
+
const a = before.split('\n');
|
|
40
|
+
const b = after.split('\n');
|
|
41
|
+
const m = a.length;
|
|
42
|
+
const n = b.length;
|
|
43
|
+
// lcs[i][j] = length of the LCS of a[i:] and b[j:]
|
|
44
|
+
const lcs = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
45
|
+
for (let i = m - 1; i >= 0; i -= 1) {
|
|
46
|
+
for (let j = n - 1; j >= 0; j -= 1) {
|
|
47
|
+
lcs[i][j] =
|
|
48
|
+
a[i] === b[j]
|
|
49
|
+
? lcs[i + 1][j + 1] + 1
|
|
50
|
+
: Math.max(lcs[i + 1][j], lcs[i][j + 1]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const out = [];
|
|
54
|
+
let i = 0;
|
|
55
|
+
let j = 0;
|
|
56
|
+
while (i < m && j < n) {
|
|
57
|
+
if (a[i] === b[j]) {
|
|
58
|
+
out.push({ op: 'context', text: a[i] });
|
|
59
|
+
i += 1;
|
|
60
|
+
j += 1;
|
|
61
|
+
}
|
|
62
|
+
else if (lcs[i + 1][j] >= lcs[i][j + 1]) {
|
|
63
|
+
out.push({ op: 'remove', text: a[i] });
|
|
64
|
+
i += 1;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
out.push({ op: 'add', text: b[j] });
|
|
68
|
+
j += 1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
while (i < m) {
|
|
72
|
+
out.push({ op: 'remove', text: a[i] });
|
|
73
|
+
i += 1;
|
|
74
|
+
}
|
|
75
|
+
while (j < n) {
|
|
76
|
+
out.push({ op: 'add', text: b[j] });
|
|
77
|
+
j += 1;
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
const MARKER = { context: ' ', add: '+', remove: '-' };
|
|
82
|
+
export class TosiDiff extends Component {
|
|
83
|
+
static preferredTagName = 'tosi-diff';
|
|
84
|
+
// `before`/`after` would collide with the native Element.before()/after()
|
|
85
|
+
// methods, so the component props are `original`/`modified`.
|
|
86
|
+
static initAttributes = {
|
|
87
|
+
original: '',
|
|
88
|
+
modified: '',
|
|
89
|
+
};
|
|
90
|
+
static shadowStyleSpec = {
|
|
91
|
+
':host': {
|
|
92
|
+
display: 'block',
|
|
93
|
+
overflow: 'auto',
|
|
94
|
+
font: 'var(--tosi-code-font, 12px/1.5 monospace)',
|
|
95
|
+
background: 'var(--tosi-diff-bg, #fff)',
|
|
96
|
+
color: 'var(--tosi-diff-color, #222)',
|
|
97
|
+
},
|
|
98
|
+
// `:host{display:block}` would otherwise beat the UA `[hidden]` rule, so the
|
|
99
|
+
// element couldn't be hidden via the attribute — restore that.
|
|
100
|
+
':host([hidden])': {
|
|
101
|
+
display: 'none',
|
|
102
|
+
},
|
|
103
|
+
'.diff-line': {
|
|
104
|
+
display: 'grid',
|
|
105
|
+
gridTemplateColumns: '1.5em 1fr',
|
|
106
|
+
whiteSpace: 'pre-wrap',
|
|
107
|
+
wordBreak: 'break-word',
|
|
108
|
+
},
|
|
109
|
+
'.diff-line .marker': {
|
|
110
|
+
textAlign: 'center',
|
|
111
|
+
userSelect: 'none',
|
|
112
|
+
opacity: '0.5',
|
|
113
|
+
},
|
|
114
|
+
'.diff-add': {
|
|
115
|
+
background: 'var(--tosi-diff-add-bg, #e6ffed)',
|
|
116
|
+
},
|
|
117
|
+
'.diff-add .marker': { color: 'var(--tosi-diff-add-color, #22863a)' },
|
|
118
|
+
'.diff-remove': {
|
|
119
|
+
background: 'var(--tosi-diff-remove-bg, #ffeef0)',
|
|
120
|
+
},
|
|
121
|
+
'.diff-remove .marker': { color: 'var(--tosi-diff-remove-color, #cb2431)' },
|
|
122
|
+
};
|
|
123
|
+
content = () => [div({ part: 'body' })];
|
|
124
|
+
render() {
|
|
125
|
+
super.render();
|
|
126
|
+
const lines = diffLines(this.original, this.modified);
|
|
127
|
+
this.parts.body.replaceChildren(...lines.map((line) => div({ class: `diff-line diff-${line.op}` }, span({ class: 'marker' }, MARKER[line.op]),
|
|
128
|
+
// Non-breaking fallback so empty lines keep their row height.
|
|
129
|
+
span({ class: 'text' }, line.text === '' ? ' ' : line.text))));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export const tosiDiff = TosiDiff.elementCreator();
|
package/dist/doc-browser.d.ts
CHANGED
|
@@ -46,8 +46,12 @@ export interface LinkItem {
|
|
|
46
46
|
* - 'query' (default, legacy): single-page app, links are `?filename`.
|
|
47
47
|
* - 'path': clean per-page URLs (`/slug/`), for the static pre-rendered site
|
|
48
48
|
* driven by <tosi-doc-system>. Requires a real page to exist at each path.
|
|
49
|
+
* - 'memory': self-contained — navigation never touches window.history/location
|
|
50
|
+
* and the instance ignores the page URL. For an embedded/nested browser (a
|
|
51
|
+
* live demo, a floating help panel). Drive it via `initialRoute` +
|
|
52
|
+
* `onRouteChange`, and the returned element's `.navigate(slug)` method.
|
|
49
53
|
*/
|
|
50
|
-
export type DocRoutingMode = 'query' | 'path';
|
|
54
|
+
export type DocRoutingMode = 'query' | 'path' | 'memory';
|
|
51
55
|
export interface DocBrowserOptions {
|
|
52
56
|
docs: Doc[];
|
|
53
57
|
context?: Record<string, any>;
|
|
@@ -56,6 +60,16 @@ export interface DocBrowserOptions {
|
|
|
56
60
|
navSize?: number;
|
|
57
61
|
minSize?: number;
|
|
58
62
|
routing?: DocRoutingMode;
|
|
63
|
+
/**
|
|
64
|
+
* Memory routing only: the slug to show first (instead of the page URL / first
|
|
65
|
+
* doc). Lets a host mount the browser already pointed at a specific doc.
|
|
66
|
+
*/
|
|
67
|
+
initialRoute?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Memory routing only: called with the current doc's slug whenever in-app
|
|
70
|
+
* navigation happens, so a host can reflect it (e.g. to an attribute).
|
|
71
|
+
*/
|
|
72
|
+
onRouteChange?: (slug: string) => void;
|
|
59
73
|
/**
|
|
60
74
|
* Header-bar links. When provided, these replace the legacy `projectLinks` icon
|
|
61
75
|
* set in the header (each renders as an icon if `icon` names a known icon, else
|