@blokkli/editor 2.0.0-alpha.39 → 2.0.0-alpha.40
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/module.json +1 -1
- package/dist/module.mjs +15 -105
- package/dist/modules/agent/index.d.mts +1 -0
- package/dist/modules/agent/index.mjs +81 -8
- package/dist/modules/agent/runtime/app/composables/agentProvider.d.ts +8 -3
- package/dist/modules/agent/runtime/app/composables/agentProvider.js +108 -13
- package/dist/modules/agent/runtime/app/features/agent/Panel/DebugGallery/index.vue +7 -6
- package/dist/modules/agent/runtime/app/features/agent/Panel/index.d.vue.ts +2 -2
- package/dist/modules/agent/runtime/app/features/agent/Panel/index.vue +12 -10
- package/dist/modules/agent/runtime/app/features/agent/Panel/index.vue.d.ts +2 -2
- package/dist/modules/agent/runtime/app/features/agent/index.vue +29 -5
- package/dist/modules/agent/runtime/app/helpers/pageStructure.js +7 -17
- package/dist/modules/agent/runtime/app/prompts/fixReadability.d.ts +2 -0
- package/dist/modules/agent/runtime/app/prompts/fixReadability.js +49 -0
- package/dist/modules/agent/runtime/app/tools/add_paragraphs/index.js +1 -0
- package/dist/modules/agent/runtime/app/tools/check_readability/index.js +24 -15
- package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/Component.d.vue.ts +46 -0
- package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/Component.vue +739 -0
- package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/Component.vue.d.ts +46 -0
- package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/Details/index.d.vue.ts +6 -0
- package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/Details/index.vue +38 -0
- package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/Details/index.vue.d.ts +6 -0
- package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/index.d.ts +38 -0
- package/dist/modules/agent/runtime/app/tools/delegate_text_rewrite/index.js +115 -0
- package/dist/modules/agent/runtime/app/tools/delete_paragraphs/index.js +1 -0
- package/dist/modules/agent/runtime/app/tools/get_all_page_content/index.js +3 -5
- package/dist/modules/agent/runtime/app/tools/get_bundle_info/index.js +1 -0
- package/dist/modules/agent/runtime/app/tools/get_child_paragraphs/index.js +1 -0
- package/dist/modules/agent/runtime/app/tools/get_content_fields/index.js +4 -7
- package/dist/modules/agent/runtime/app/tools/get_page_structure/index.js +1 -0
- package/dist/modules/agent/runtime/app/tools/get_paragraph_context/index.js +10 -17
- package/dist/modules/agent/runtime/app/tools/get_paragraph_options/index.js +1 -0
- package/dist/modules/agent/runtime/app/tools/get_paragraphs_in_viewport/index.js +1 -0
- package/dist/modules/agent/runtime/app/tools/get_readability_issues/index.js +17 -70
- package/dist/modules/agent/runtime/app/tools/get_selected_paragraphs/index.js +1 -0
- package/dist/modules/agent/runtime/app/tools/helpers.d.ts +38 -10
- package/dist/modules/agent/runtime/app/tools/helpers.js +90 -27
- package/dist/modules/agent/runtime/app/tools/move_paragraphs/index.js +1 -0
- package/dist/modules/agent/runtime/app/tools/rearrange_paragraphs/index.js +1 -0
- package/dist/modules/agent/runtime/app/tools/schemas.d.ts +1 -1
- package/dist/modules/agent/runtime/app/tools/update_text_fields/Component.vue +66 -84
- package/dist/modules/agent/runtime/app/tools/update_text_fields/index.d.ts +8 -1
- package/dist/modules/agent/runtime/app/tools/update_text_fields/index.js +21 -14
- package/dist/modules/agent/runtime/app/types/index.d.ts +41 -0
- package/dist/modules/agent/runtime/server/Session.d.ts +8 -1
- package/dist/modules/agent/runtime/server/Session.js +154 -6
- package/dist/modules/agent/runtime/server/agent.js +5 -1
- package/dist/modules/agent/runtime/server/default-skills/fixReadability.js +31 -51
- package/dist/modules/agent/runtime/server/default-skills/rewriteAndTranslate.js +45 -4
- package/dist/modules/agent/runtime/server/providers/anthropic.js +2 -1
- package/dist/modules/agent/runtime/server/providers/openai.js +2 -1
- package/dist/modules/agent/runtime/server/providers/types.d.ts +2 -0
- package/dist/modules/agent/runtime/server/route.d.ts +2 -0
- package/dist/modules/agent/runtime/server/route.js +40 -0
- package/dist/modules/agent/runtime/server/routing.d.ts +18 -0
- package/dist/modules/agent/runtime/server/routing.js +111 -0
- package/dist/modules/agent/runtime/server/skills/types.d.ts +10 -0
- package/dist/modules/agent/runtime/server/stream.d.ts +2 -0
- package/dist/modules/agent/runtime/server/stream.js +190 -0
- package/dist/modules/agent/runtime/server/streamParser.d.ts +85 -0
- package/dist/modules/agent/runtime/server/streamParser.js +227 -0
- package/dist/modules/agent/runtime/server/templates/defineStreamTemplate.d.ts +21 -0
- package/dist/modules/agent/runtime/server/templates/defineStreamTemplate.js +3 -0
- package/dist/modules/agent/runtime/server/templates/definitions/fixReadability.d.ts +26 -0
- package/dist/modules/agent/runtime/server/templates/definitions/fixReadability.js +84 -0
- package/dist/modules/agent/runtime/server/templates/definitions/generateContent.d.ts +6 -0
- package/dist/modules/agent/runtime/server/templates/definitions/generateContent.js +29 -0
- package/dist/modules/agent/runtime/server/templates/definitions/rewrite.d.ts +5 -0
- package/dist/modules/agent/runtime/server/templates/definitions/rewrite.js +14 -0
- package/dist/modules/agent/runtime/server/templates/definitions/translate.d.ts +5 -0
- package/dist/modules/agent/runtime/server/templates/definitions/translate.js +23 -0
- package/dist/modules/agent/runtime/server/templates/index.d.ts +37 -0
- package/dist/modules/agent/runtime/server/templates/index.js +25 -0
- package/dist/modules/agent/runtime/server/templates/types.d.ts +17 -0
- package/dist/modules/agent/runtime/server/templates/types.js +0 -0
- package/dist/modules/agent/runtime/server/templates/utils.d.ts +5 -0
- package/dist/modules/agent/runtime/server/templates/utils.js +69 -0
- package/dist/modules/agent/runtime/shared/types.d.ts +18 -0
- package/dist/modules/agent/runtime/shared/types.js +16 -1
- package/dist/runtime/components/BlokkliItem.d.vue.ts +1 -1
- package/dist/runtime/components/BlokkliItem.vue +34 -3
- package/dist/runtime/components/BlokkliItem.vue.d.ts +1 -1
- package/dist/runtime/editor/components/Actions/index.vue +2 -2
- package/dist/runtime/editor/components/AnimationCanvas/index.vue +23 -2
- package/dist/runtime/editor/components/DiffApproval/Highlight/Item.d.vue.ts +19 -0
- package/dist/runtime/editor/components/DiffApproval/Highlight/Item.vue +106 -0
- package/dist/runtime/editor/components/DiffApproval/Highlight/Item.vue.d.ts +19 -0
- package/dist/runtime/editor/components/DiffApproval/Highlight/index.d.vue.ts +22 -0
- package/dist/runtime/editor/components/DiffApproval/Highlight/index.vue +50 -0
- package/dist/runtime/editor/components/DiffApproval/Highlight/index.vue.d.ts +22 -0
- package/dist/runtime/editor/components/DiffApproval/Toolbar/index.d.vue.ts +24 -0
- package/dist/runtime/editor/components/DiffApproval/Toolbar/index.vue +113 -0
- package/dist/runtime/editor/components/DiffApproval/Toolbar/index.vue.d.ts +24 -0
- package/dist/runtime/editor/components/DiffApproval/index.d.vue.ts +19 -0
- package/dist/runtime/editor/components/DiffApproval/index.vue +158 -0
- package/dist/runtime/editor/components/DiffApproval/index.vue.d.ts +19 -0
- package/dist/runtime/editor/components/DiffApproval/types.d.ts +7 -0
- package/dist/runtime/editor/components/DiffApproval/types.js +0 -0
- package/dist/runtime/editor/components/DiffViewer/DiffValue.vue +2 -11
- package/dist/runtime/editor/components/DraggableList.vue +1 -1
- package/dist/runtime/editor/components/EditProvider.vue +18 -1
- package/dist/runtime/editor/components/ShortcutIndicator/index.d.vue.ts +2 -2
- package/dist/runtime/editor/components/ShortcutIndicator/index.vue +27 -33
- package/dist/runtime/editor/components/ShortcutIndicator/index.vue.d.ts +2 -2
- package/dist/runtime/editor/components/index.d.ts +2 -1
- package/dist/runtime/editor/components/index.js +2 -0
- package/dist/runtime/editor/composables/useEditableFieldOverride.d.ts +2 -0
- package/dist/runtime/editor/composables/useEditableFieldOverride.js +21 -15
- package/dist/runtime/editor/css/output.css +1 -1
- package/dist/runtime/editor/events/index.d.ts +3 -0
- package/dist/runtime/editor/features/add-list/index.vue +1 -0
- package/dist/runtime/editor/features/analyze/Main.vue +1 -1
- package/dist/runtime/editor/features/analyze/analyzers/helpers/Context.d.ts +7 -2
- package/dist/runtime/editor/features/analyze/analyzers/helpers/Context.js +6 -1
- package/dist/runtime/editor/features/analyze/analyzers/readability.js +52 -222
- package/dist/runtime/editor/features/analyze/analyzers/types.d.ts +2 -2
- package/dist/runtime/editor/features/analyze/readability/adapterTypes.d.ts +9 -0
- package/dist/runtime/editor/features/analyze/readability/adapterTypes.js +0 -0
- package/dist/runtime/editor/features/analyze/readability/builtinAnalyzer.d.ts +6 -0
- package/dist/runtime/editor/features/analyze/readability/builtinAnalyzer.js +200 -0
- package/dist/runtime/editor/features/analyze/readability/chunkHtml.d.ts +15 -0
- package/dist/runtime/editor/features/analyze/readability/chunkHtml.js +97 -0
- package/dist/runtime/editor/features/analyze/readability/types.d.ts +72 -0
- package/dist/runtime/editor/features/analyze/readability/types.js +0 -0
- package/dist/runtime/editor/features/artboard/Renderer.vue +9 -5
- package/dist/runtime/editor/features/breadcrumbs/index.vue +1 -1
- package/dist/runtime/editor/features/dragging-overlay/index.vue +1 -1
- package/dist/runtime/editor/features/editable-field/index.vue +1 -1
- package/dist/runtime/editor/features/hover/index.vue +1 -1
- package/dist/runtime/editor/features/options/index.vue +1 -1
- package/dist/runtime/editor/features/selection/AddButtons/Renderer/index.vue +1 -1
- package/dist/runtime/editor/features/selection/index.vue +2 -2
- package/dist/runtime/editor/features/structure/List/Item/index.vue +1 -3
- package/dist/runtime/editor/helpers/diff/index.d.ts +11 -0
- package/dist/runtime/editor/helpers/diff/index.js +227 -0
- package/dist/runtime/editor/plugins/Sidebar/index.vue +1 -1
- package/dist/runtime/editor/providers/analyze.d.ts +2 -1
- package/dist/runtime/editor/providers/analyze.js +6 -3
- package/dist/runtime/editor/providers/directive.js +1 -0
- package/dist/runtime/editor/providers/fieldValue.d.ts +54 -0
- package/dist/runtime/editor/providers/fieldValue.js +126 -0
- package/dist/runtime/editor/providers/fieldValueAdapterTypes.d.ts +13 -0
- package/dist/runtime/editor/providers/fieldValueAdapterTypes.js +0 -0
- package/dist/runtime/editor/providers/readability.d.ts +23 -0
- package/dist/runtime/editor/providers/readability.js +130 -0
- package/dist/runtime/editor/providers/state.d.ts +16 -0
- package/dist/runtime/editor/providers/state.js +19 -1
- package/dist/runtime/editor/providers/ui.d.ts +7 -0
- package/dist/runtime/editor/providers/ui.js +7 -1
- package/dist/runtime/editor/translations/de.json +80 -8
- package/dist/runtime/editor/translations/fr.json +80 -8
- package/dist/runtime/editor/translations/gsw_CH.json +80 -8
- package/dist/runtime/editor/translations/it.json +80 -8
- package/dist/runtime/editor/types/app.d.ts +4 -0
- package/dist/shared/editor.9vf8ZnOp.mjs +288 -0
- package/package.json +2 -2
- package/dist/modules/agent/runtime/app/tools/update_text_fields/Item.d.vue.ts +0 -22
- package/dist/modules/agent/runtime/app/tools/update_text_fields/Item.vue +0 -95
- package/dist/modules/agent/runtime/app/tools/update_text_fields/Item.vue.d.ts +0 -22
- package/dist/shared/editor.BFIzNSQM.mjs +0 -146
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
const BLOCK_ELEMENTS = /* @__PURE__ */ new Set([
|
|
2
|
+
"ADDRESS",
|
|
3
|
+
"ARTICLE",
|
|
4
|
+
"ASIDE",
|
|
5
|
+
"BLOCKQUOTE",
|
|
6
|
+
"DD",
|
|
7
|
+
"DIV",
|
|
8
|
+
"DL",
|
|
9
|
+
"DT",
|
|
10
|
+
"FIELDSET",
|
|
11
|
+
"FIGCAPTION",
|
|
12
|
+
"FIGURE",
|
|
13
|
+
"FOOTER",
|
|
14
|
+
"FORM",
|
|
15
|
+
"H1",
|
|
16
|
+
"H2",
|
|
17
|
+
"H3",
|
|
18
|
+
"H4",
|
|
19
|
+
"H5",
|
|
20
|
+
"H6",
|
|
21
|
+
"HEADER",
|
|
22
|
+
"HR",
|
|
23
|
+
"LI",
|
|
24
|
+
"MAIN",
|
|
25
|
+
"NAV",
|
|
26
|
+
"OL",
|
|
27
|
+
"P",
|
|
28
|
+
"PRE",
|
|
29
|
+
"SECTION",
|
|
30
|
+
"TABLE",
|
|
31
|
+
"TD",
|
|
32
|
+
"TH",
|
|
33
|
+
"UL",
|
|
34
|
+
"DETAILS",
|
|
35
|
+
"SUMMARY",
|
|
36
|
+
"DIALOG"
|
|
37
|
+
]);
|
|
38
|
+
function isBlockElement(el) {
|
|
39
|
+
return BLOCK_ELEMENTS.has(el.tagName);
|
|
40
|
+
}
|
|
41
|
+
function containsBlockElements(el) {
|
|
42
|
+
for (const child of el.children) {
|
|
43
|
+
if (isBlockElement(child)) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
if (containsBlockElements(child)) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
function traverse(el, results) {
|
|
53
|
+
if (el.tagName === "SCRIPT" || el.tagName === "STYLE") {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (isBlockElement(el)) {
|
|
57
|
+
if (!containsBlockElements(el)) {
|
|
58
|
+
const text = (el.textContent || "").trim();
|
|
59
|
+
if (text) {
|
|
60
|
+
results.push({
|
|
61
|
+
text,
|
|
62
|
+
html: el.innerHTML
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
for (const child of el.children) {
|
|
67
|
+
traverse(child, results);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
for (const child of el.children) {
|
|
72
|
+
traverse(child, results);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export function chunkHtml(value, fieldType) {
|
|
77
|
+
const trimmed = value.trim();
|
|
78
|
+
if (!trimmed) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
if (fieldType === "plain") {
|
|
82
|
+
return [{ text: trimmed }];
|
|
83
|
+
}
|
|
84
|
+
const parser = new DOMParser();
|
|
85
|
+
const doc = parser.parseFromString(trimmed, "text/html");
|
|
86
|
+
const results = [];
|
|
87
|
+
for (const child of doc.body.children) {
|
|
88
|
+
traverse(child, results);
|
|
89
|
+
}
|
|
90
|
+
if (results.length === 0) {
|
|
91
|
+
const text = (doc.body.textContent || "").trim();
|
|
92
|
+
if (text) {
|
|
93
|
+
results.push({ text, html: doc.body.innerHTML });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return results;
|
|
97
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { AnalyzeImpact } from '../analyzers/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Classification band for a chunk of text.
|
|
4
|
+
*/
|
|
5
|
+
export type ReadabilityBand = 'easy' | 'ok' | 'hard';
|
|
6
|
+
/**
|
|
7
|
+
* Result for a single chunk of text within a field.
|
|
8
|
+
*/
|
|
9
|
+
export type ReadabilityChunkResult = {
|
|
10
|
+
text: string;
|
|
11
|
+
html?: string;
|
|
12
|
+
score: number;
|
|
13
|
+
band: ReadabilityBand;
|
|
14
|
+
impact: AnalyzeImpact;
|
|
15
|
+
description?: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Result for a single field, containing all its scored chunks.
|
|
19
|
+
*/
|
|
20
|
+
export type ReadabilityFieldResult = {
|
|
21
|
+
rawValue: string;
|
|
22
|
+
fieldType: 'plain' | 'markup';
|
|
23
|
+
chunks: ReadabilityChunkResult[];
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Full analysis result keyed by "{uuid}/{fieldName}".
|
|
27
|
+
*/
|
|
28
|
+
export type ReadabilityAnalysisResult = Record<string, ReadabilityFieldResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Interface for a readability analyzer.
|
|
31
|
+
*
|
|
32
|
+
* One analyzer is active at a time. The built-in default uses
|
|
33
|
+
* LIX/CLI/ARI/Gulpease. Adapters can override with a custom implementation
|
|
34
|
+
* (e.g. CEFR via API).
|
|
35
|
+
*/
|
|
36
|
+
export type ReadabilityAnalyzer = {
|
|
37
|
+
id: string;
|
|
38
|
+
label?: string | ((langcode: string) => string);
|
|
39
|
+
description?: string;
|
|
40
|
+
supportedLanguages?: string[];
|
|
41
|
+
minWordsForConfidence?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Short label for the primary score metric (e.g. "LIX", "Gulpease", "CEFR").
|
|
44
|
+
* Used by the UI to display scores like "LIX: 45".
|
|
45
|
+
*/
|
|
46
|
+
scoreLabel: string;
|
|
47
|
+
/**
|
|
48
|
+
* Optional initialization (e.g. lazy-load a library).
|
|
49
|
+
*/
|
|
50
|
+
init?(langcode: string): void | Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Score an array of plain-text strings.
|
|
53
|
+
* Returns one primary score per input text (null if not scorable).
|
|
54
|
+
*/
|
|
55
|
+
analyze(texts: string[], langcode: string): Promise<(number | null)[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Classify a score into a readability band.
|
|
58
|
+
*/
|
|
59
|
+
classifyBand(score: number, langcode: string): ReadabilityBand;
|
|
60
|
+
/**
|
|
61
|
+
* Determine the impact severity for a score.
|
|
62
|
+
*/
|
|
63
|
+
impactForScore(score: number): AnalyzeImpact;
|
|
64
|
+
/**
|
|
65
|
+
* Return context text for the agent prompt (e.g. LIX reference table).
|
|
66
|
+
*/
|
|
67
|
+
getAgentContext(): string;
|
|
68
|
+
/**
|
|
69
|
+
* Optional display formatting for a score value.
|
|
70
|
+
*/
|
|
71
|
+
formatScore?(value: number): string;
|
|
72
|
+
};
|
|
File without changes
|
|
@@ -272,11 +272,11 @@ onBlokkliEvent("keyPressed", (e) => {
|
|
|
272
272
|
e.originalEvent.preventDefault();
|
|
273
273
|
artboard.scrollPageDown();
|
|
274
274
|
animation.requestDraw();
|
|
275
|
-
} else if (e.code === "ArrowUp") {
|
|
275
|
+
} else if (e.code === "ArrowUp" && !ui.isApproving.value) {
|
|
276
276
|
e.originalEvent.preventDefault();
|
|
277
277
|
artboard.scrollUp();
|
|
278
278
|
animation.requestDraw();
|
|
279
|
-
} else if (e.code === "ArrowDown") {
|
|
279
|
+
} else if (e.code === "ArrowDown" && !ui.isApproving.value) {
|
|
280
280
|
e.originalEvent.preventDefault();
|
|
281
281
|
artboard.scrollDown();
|
|
282
282
|
animation.requestDraw();
|
|
@@ -303,7 +303,8 @@ onBlokkliEvent("scrollIntoView", (e) => {
|
|
|
303
303
|
artboard.scrollIntoView(rect, {
|
|
304
304
|
scale: "none",
|
|
305
305
|
axis: "y",
|
|
306
|
-
behavior: e.immediate ? "instant" : "auto"
|
|
306
|
+
behavior: e.immediate ? "instant" : "auto",
|
|
307
|
+
area: "blocking"
|
|
307
308
|
});
|
|
308
309
|
} else {
|
|
309
310
|
if (artboardElement.contains(e.element)) {
|
|
@@ -313,8 +314,11 @@ onBlokkliEvent("scrollIntoView", (e) => {
|
|
|
313
314
|
}
|
|
314
315
|
artboard.scrollElementIntoView(e.element, {
|
|
315
316
|
scale: "none",
|
|
316
|
-
axis: "
|
|
317
|
-
behavior: e.immediate ? "instant" : "auto"
|
|
317
|
+
axis: "both",
|
|
318
|
+
behavior: e.immediate ? "instant" : "auto",
|
|
319
|
+
area: "blocking",
|
|
320
|
+
block: "auto",
|
|
321
|
+
inline: "auto"
|
|
318
322
|
});
|
|
319
323
|
} else {
|
|
320
324
|
artboard.scrollToTop({
|
|
@@ -17,7 +17,7 @@ defineBlokkliFeature({
|
|
|
17
17
|
const { selection, ui, dom, animation, $t } = useBlokkli();
|
|
18
18
|
const isLocked = ref(false);
|
|
19
19
|
const isVisible = computed(
|
|
20
|
-
() => !isLocked.value && dom.isReady.value && !selection.isMultiSelecting.value && !selection.activeEditableLabel.value && !selection.isDragging.value && !ui.hasTransformOverlayOpen.value && !ui.hasDialogOpen.value && !ui.hasNestedEditorOpen.value && !ui.isAnimating.value
|
|
20
|
+
() => !isLocked.value && dom.isReady.value && !selection.isMultiSelecting.value && !selection.activeEditableLabel.value && !selection.isDragging.value && !ui.hasTransformOverlayOpen.value && !ui.hasDialogOpen.value && !ui.hasNestedEditorOpen.value && !ui.isAnimating.value && !ui.isApproving.value
|
|
21
21
|
);
|
|
22
22
|
</script>
|
|
23
23
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<Teleport to="#bk-blokkli-item-actions-controls">
|
|
3
3
|
<OptionsForm
|
|
4
4
|
v-if="
|
|
5
|
-
definition && !selection.isDragging.value && !ui.isAnimating.value && uuids
|
|
5
|
+
definition && !selection.isDragging.value && !ui.isAnimating.value && !ui.isTransforming.value && uuids
|
|
6
6
|
"
|
|
7
7
|
:key="key + state.refreshKey.value + ui.isAnimating.value"
|
|
8
8
|
:uuids
|
|
@@ -348,7 +348,7 @@ const { collector } = defineRenderer("add-buttons", {
|
|
|
348
348
|
if (ui.openTooltip.value && ui.openTooltip.value !== "add-buttons") {
|
|
349
349
|
return false;
|
|
350
350
|
}
|
|
351
|
-
if (ui.hasTransformOverlayOpen.value) {
|
|
351
|
+
if (ui.hasTransformOverlayOpen.value || ui.isApproving.value) {
|
|
352
352
|
return false;
|
|
353
353
|
}
|
|
354
354
|
return true;
|
|
@@ -80,7 +80,7 @@ const stop = watch(
|
|
|
80
80
|
}
|
|
81
81
|
);
|
|
82
82
|
const isVisible = computed(
|
|
83
|
-
() => dom.isReady.value && !selection.isMultiSelecting.value && !selection.activeEditableLabel.value && !selection.isDragging.value && !ui.isAnimating.value && hasSelectedOnce.value
|
|
83
|
+
() => dom.isReady.value && !selection.isMultiSelecting.value && !selection.activeEditableLabel.value && !selection.isDragging.value && !ui.isAnimating.value && hasSelectedOnce.value && !ui.isApproving.value
|
|
84
84
|
);
|
|
85
85
|
const findMostVisibleBlock = () => {
|
|
86
86
|
const viewport = ui.visibleViewportPadded.value;
|
|
@@ -240,7 +240,7 @@ onBlokkliEvent("keyPressed", (e) => {
|
|
|
240
240
|
eventBus.emit("select:host:unselect");
|
|
241
241
|
}
|
|
242
242
|
} else if (e.code === "Tab") {
|
|
243
|
-
if (tour.isTouring.value || ui.hasDialogOpen.value || ui.hasNestedEditorOpen.value) {
|
|
243
|
+
if (tour.isTouring.value || ui.hasDialogOpen.value || ui.hasNestedEditorOpen.value || ui.isApproving.value) {
|
|
244
244
|
return;
|
|
245
245
|
}
|
|
246
246
|
e.originalEvent.preventDefault();
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute an inline HTML diff between two strings.
|
|
3
|
+
*
|
|
4
|
+
* For content with block-level HTML elements (p, h1-h6, etc.), aligns blocks
|
|
5
|
+
* by tag name and diffs within each block individually, preventing diff markers
|
|
6
|
+
* from crossing element boundaries.
|
|
7
|
+
*
|
|
8
|
+
* For plain text or inline-only HTML, uses flat word-level diffing with
|
|
9
|
+
* post-processing to merge long runs of consecutive modifications.
|
|
10
|
+
*/
|
|
11
|
+
export declare function computeDiff(before: string, after: string): string;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import diff from "html-diff-ts";
|
|
2
|
+
const PAIR_RE = /<del class="diffmod">((?:[^<]|<(?!\/del>))*?)<\/del><ins class="diffmod">((?:[^<]|<(?!\/ins>))*?)<\/ins>/g;
|
|
3
|
+
function tokenize(html) {
|
|
4
|
+
const tokens = [];
|
|
5
|
+
let lastIndex = 0;
|
|
6
|
+
PAIR_RE.lastIndex = 0;
|
|
7
|
+
let match = PAIR_RE.exec(html);
|
|
8
|
+
while (match) {
|
|
9
|
+
if (match.index > lastIndex) {
|
|
10
|
+
tokens.push({ type: "other", text: html.slice(lastIndex, match.index) });
|
|
11
|
+
}
|
|
12
|
+
tokens.push({
|
|
13
|
+
type: "pair",
|
|
14
|
+
del: match[1] || "",
|
|
15
|
+
ins: match[2] || "",
|
|
16
|
+
raw: match[0]
|
|
17
|
+
});
|
|
18
|
+
lastIndex = match.index + match[0].length;
|
|
19
|
+
match = PAIR_RE.exec(html);
|
|
20
|
+
}
|
|
21
|
+
if (lastIndex < html.length) {
|
|
22
|
+
tokens.push({ type: "other", text: html.slice(lastIndex) });
|
|
23
|
+
}
|
|
24
|
+
return tokens;
|
|
25
|
+
}
|
|
26
|
+
function isMergeableSeparator(text) {
|
|
27
|
+
if (/<[^>]+>/.test(text)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
if (/^(?:\s| )*$/.test(text)) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
return text.length <= 20;
|
|
34
|
+
}
|
|
35
|
+
function cleanupDiffMods(html) {
|
|
36
|
+
const tokens = tokenize(html);
|
|
37
|
+
const runs = [];
|
|
38
|
+
let i = 0;
|
|
39
|
+
while (i < tokens.length) {
|
|
40
|
+
const token = tokens[i];
|
|
41
|
+
if (token?.type !== "pair") {
|
|
42
|
+
i++;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const run = { startIndex: i, endIndex: i + 1, pairCount: 1 };
|
|
46
|
+
let j = i + 1;
|
|
47
|
+
while (j < tokens.length) {
|
|
48
|
+
const next = tokens[j];
|
|
49
|
+
if (!next) break;
|
|
50
|
+
if (next.type === "pair") {
|
|
51
|
+
run.endIndex = j + 1;
|
|
52
|
+
run.pairCount++;
|
|
53
|
+
j++;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const afterNext = tokens[j + 1];
|
|
57
|
+
if (next.type === "other" && isMergeableSeparator(next.text) && afterNext?.type === "pair") {
|
|
58
|
+
run.endIndex = j + 2;
|
|
59
|
+
run.pairCount++;
|
|
60
|
+
j += 2;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
runs.push(run);
|
|
66
|
+
i = run.endIndex;
|
|
67
|
+
}
|
|
68
|
+
const mergeSet = /* @__PURE__ */ new Set();
|
|
69
|
+
const mergeRuns = runs.filter((r) => r.pairCount >= 3);
|
|
70
|
+
for (const run of mergeRuns) {
|
|
71
|
+
for (let k = run.startIndex; k < run.endIndex; k++) {
|
|
72
|
+
mergeSet.add(k);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (mergeRuns.length === 0) {
|
|
76
|
+
return html;
|
|
77
|
+
}
|
|
78
|
+
let result = "";
|
|
79
|
+
let ri = 0;
|
|
80
|
+
for (let k = 0; k < tokens.length; k++) {
|
|
81
|
+
if (ri < mergeRuns.length && k === mergeRuns[ri]?.startIndex) {
|
|
82
|
+
const run = mergeRuns[ri];
|
|
83
|
+
const dels = [];
|
|
84
|
+
const inss = [];
|
|
85
|
+
for (let m = run.startIndex; m < run.endIndex; m++) {
|
|
86
|
+
const t2 = tokens[m];
|
|
87
|
+
if (t2.type === "pair") {
|
|
88
|
+
dels.push(t2.del);
|
|
89
|
+
inss.push(t2.ins);
|
|
90
|
+
} else {
|
|
91
|
+
dels.push(t2.text);
|
|
92
|
+
inss.push(t2.text);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
result += `<del>${dels.join("")}</del><ins>${inss.join("")}</ins>`;
|
|
96
|
+
k = run.endIndex - 1;
|
|
97
|
+
ri++;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const t = tokens[k];
|
|
101
|
+
result += t.type === "pair" ? t.raw : t.text;
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
const BLOCK_TAGS = /* @__PURE__ */ new Set([
|
|
106
|
+
"p",
|
|
107
|
+
"h1",
|
|
108
|
+
"h2",
|
|
109
|
+
"h3",
|
|
110
|
+
"h4",
|
|
111
|
+
"h5",
|
|
112
|
+
"h6",
|
|
113
|
+
"ul",
|
|
114
|
+
"ol",
|
|
115
|
+
"blockquote",
|
|
116
|
+
"pre",
|
|
117
|
+
"div",
|
|
118
|
+
"table",
|
|
119
|
+
"figure",
|
|
120
|
+
"section",
|
|
121
|
+
"article"
|
|
122
|
+
]);
|
|
123
|
+
function parseBlocks(html) {
|
|
124
|
+
const container = document.createElement("div");
|
|
125
|
+
container.innerHTML = html;
|
|
126
|
+
const blocks = [];
|
|
127
|
+
for (const child of container.childNodes) {
|
|
128
|
+
if (child.nodeType === Node.ELEMENT_NODE) {
|
|
129
|
+
const el = child;
|
|
130
|
+
const tag = el.tagName.toLowerCase();
|
|
131
|
+
if (!BLOCK_TAGS.has(tag)) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
let openTag = `<${tag}`;
|
|
135
|
+
for (const attr of el.attributes) {
|
|
136
|
+
openTag += ` ${attr.name}="${attr.value}"`;
|
|
137
|
+
}
|
|
138
|
+
openTag += ">";
|
|
139
|
+
blocks.push({ tag, innerHTML: el.innerHTML, openTag });
|
|
140
|
+
} else if (child.nodeType === Node.TEXT_NODE && child.textContent?.trim()) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return blocks;
|
|
145
|
+
}
|
|
146
|
+
function alignBlocks(before, after) {
|
|
147
|
+
const m = before.length;
|
|
148
|
+
const n = after.length;
|
|
149
|
+
const dp = Array.from(
|
|
150
|
+
{ length: m + 1 },
|
|
151
|
+
() => Array(n + 1).fill(0)
|
|
152
|
+
);
|
|
153
|
+
for (let i2 = 1; i2 <= m; i2++) {
|
|
154
|
+
for (let j2 = 1; j2 <= n; j2++) {
|
|
155
|
+
if (before[i2 - 1].tag === after[j2 - 1].tag) {
|
|
156
|
+
dp[i2][j2] = dp[i2 - 1][j2 - 1] + 1;
|
|
157
|
+
} else {
|
|
158
|
+
dp[i2][j2] = Math.max(dp[i2 - 1][j2], dp[i2][j2 - 1]);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const entries = [];
|
|
163
|
+
let i = m;
|
|
164
|
+
let j = n;
|
|
165
|
+
while (i > 0 && j > 0) {
|
|
166
|
+
if (before[i - 1].tag === after[j - 1].tag) {
|
|
167
|
+
entries.push({
|
|
168
|
+
type: "match",
|
|
169
|
+
before: before[i - 1],
|
|
170
|
+
after: after[j - 1]
|
|
171
|
+
});
|
|
172
|
+
i--;
|
|
173
|
+
j--;
|
|
174
|
+
} else if (dp[i - 1][j] >= dp[i][j - 1]) {
|
|
175
|
+
entries.push({ type: "delete", before: before[i - 1] });
|
|
176
|
+
i--;
|
|
177
|
+
} else {
|
|
178
|
+
entries.push({ type: "insert", after: after[j - 1] });
|
|
179
|
+
j--;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
while (i > 0) {
|
|
183
|
+
entries.push({ type: "delete", before: before[i - 1] });
|
|
184
|
+
i--;
|
|
185
|
+
}
|
|
186
|
+
while (j > 0) {
|
|
187
|
+
entries.push({ type: "insert", after: after[j - 1] });
|
|
188
|
+
j--;
|
|
189
|
+
}
|
|
190
|
+
return entries.reverse();
|
|
191
|
+
}
|
|
192
|
+
function computeBlockDiff(before, after) {
|
|
193
|
+
const alignment = alignBlocks(before, after);
|
|
194
|
+
const parts = [];
|
|
195
|
+
for (const entry of alignment) {
|
|
196
|
+
if (entry.type === "match") {
|
|
197
|
+
if (entry.before.innerHTML === entry.after.innerHTML) {
|
|
198
|
+
parts.push(
|
|
199
|
+
`${entry.after.openTag}${entry.after.innerHTML}</${entry.after.tag}>`
|
|
200
|
+
);
|
|
201
|
+
} else {
|
|
202
|
+
const innerDiff = diff(entry.before.innerHTML, entry.after.innerHTML);
|
|
203
|
+
parts.push(
|
|
204
|
+
`${entry.after.openTag}${cleanupDiffMods(innerDiff)}</${entry.after.tag}>`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
} else if (entry.type === "delete") {
|
|
208
|
+
parts.push(
|
|
209
|
+
`${entry.before.openTag}<del>${entry.before.innerHTML}</del></${entry.before.tag}>`
|
|
210
|
+
);
|
|
211
|
+
} else {
|
|
212
|
+
parts.push(
|
|
213
|
+
`${entry.after.openTag}<ins>${entry.after.innerHTML}</ins></${entry.after.tag}>`
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return parts.join("");
|
|
218
|
+
}
|
|
219
|
+
export function computeDiff(before, after) {
|
|
220
|
+
const beforeBlocks = parseBlocks(before);
|
|
221
|
+
const afterBlocks = parseBlocks(after);
|
|
222
|
+
if (beforeBlocks && afterBlocks && (beforeBlocks.length > 0 || afterBlocks.length > 0)) {
|
|
223
|
+
return computeBlockDiff(beforeBlocks, afterBlocks);
|
|
224
|
+
}
|
|
225
|
+
const raw = diff(before, after);
|
|
226
|
+
return cleanupDiffMods(raw);
|
|
227
|
+
}
|
|
@@ -2,6 +2,7 @@ import { type Ref, type ComputedRef } from '#imports';
|
|
|
2
2
|
import type { AdaptersProvider } from './adapters.js';
|
|
3
3
|
import type { StateProvider } from './state.js';
|
|
4
4
|
import type { UiProvider } from './ui.js';
|
|
5
|
+
import type { ReadabilityProvider } from './readability.js';
|
|
5
6
|
import type { AdapterContext } from '#blokkli/editor/adapter';
|
|
6
7
|
import type { TextProvider } from './texts.js';
|
|
7
8
|
import type { AnalyzeNode, AnalyzeResult, Analyzer, AnalyzerType } from '../features/analyze/analyzers/types.js';
|
|
@@ -40,4 +41,4 @@ export type AnalyzeProvider = {
|
|
|
40
41
|
nodes: AnalyzeNode[];
|
|
41
42
|
}>>;
|
|
42
43
|
};
|
|
43
|
-
export default function analyzeProvider(adapters: AdaptersProvider, state: StateProvider, ui: UiProvider, context: ComputedRef<AdapterContext>, $t: TextProvider): AnalyzeProvider;
|
|
44
|
+
export default function analyzeProvider(adapters: AdaptersProvider, state: StateProvider, ui: UiProvider, context: ComputedRef<AdapterContext>, $t: TextProvider, readability: ReadabilityProvider): AnalyzeProvider;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ref } from "#imports";
|
|
2
2
|
import { AnalyzerContext } from "../features/analyze/analyzers/helpers/Context.js";
|
|
3
3
|
import { normalizeToArray } from "../features/analyze/analyzers/helpers/normalizeArray.js";
|
|
4
|
-
export default function analyzeProvider(adapters, state, ui, context, $t) {
|
|
4
|
+
export default function analyzeProvider(adapters, state, ui, context, $t, readability) {
|
|
5
5
|
const analyzers = ref([]);
|
|
6
6
|
const isInitialized = ref(false);
|
|
7
7
|
let initPromise = null;
|
|
@@ -12,7 +12,9 @@ export default function analyzeProvider(adapters, state, ui, context, $t) {
|
|
|
12
12
|
ui.interfaceLanguage.value,
|
|
13
13
|
ui.providerElement,
|
|
14
14
|
state,
|
|
15
|
-
$t
|
|
15
|
+
$t,
|
|
16
|
+
void 0,
|
|
17
|
+
readability
|
|
16
18
|
);
|
|
17
19
|
await Promise.all(
|
|
18
20
|
fetched.map(async (analyzer) => {
|
|
@@ -40,7 +42,8 @@ export default function analyzeProvider(adapters, state, ui, context, $t) {
|
|
|
40
42
|
element,
|
|
41
43
|
state,
|
|
42
44
|
$t,
|
|
43
|
-
signal
|
|
45
|
+
signal,
|
|
46
|
+
readability
|
|
44
47
|
);
|
|
45
48
|
}
|
|
46
49
|
async function runAnalyzer(analyzer, ctx) {
|
|
@@ -217,6 +217,7 @@ export default function(debug, ui) {
|
|
|
217
217
|
});
|
|
218
218
|
onBlokkliEvent("ui:resized", handleRefresh);
|
|
219
219
|
onBlokkliEvent("option:finish-change", handleRefresh);
|
|
220
|
+
onBlokkliEvent("ui:update-rects", handleRefresh);
|
|
220
221
|
onMounted(() => {
|
|
221
222
|
doInitTimeout();
|
|
222
223
|
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { EntityContext } from '#blokkli/types';
|
|
2
|
+
import type { AdaptersProvider } from './adapters.js';
|
|
3
|
+
import type { DefinitionProvider } from './definition.js';
|
|
4
|
+
import type { DirectiveProvider } from './directive.js';
|
|
5
|
+
import type { StateProvider } from './state.js';
|
|
6
|
+
import type { BlockDefinitionProvider } from './types.js';
|
|
7
|
+
import './fieldValueAdapterTypes.js';
|
|
8
|
+
/**
|
|
9
|
+
* Simplified field type for editable fields.
|
|
10
|
+
*/
|
|
11
|
+
export type FieldValueType = 'plain' | 'markup';
|
|
12
|
+
/**
|
|
13
|
+
* A text field value as provided by the adapter or directive system.
|
|
14
|
+
*/
|
|
15
|
+
export type TextFieldValue = {
|
|
16
|
+
uuid: string;
|
|
17
|
+
fieldName: string;
|
|
18
|
+
value: string;
|
|
19
|
+
fieldType: FieldValueType;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* The result of reading a field value.
|
|
23
|
+
*/
|
|
24
|
+
export type ReadFieldValueResult = {
|
|
25
|
+
value: string;
|
|
26
|
+
fieldType: FieldValueType;
|
|
27
|
+
};
|
|
28
|
+
export type FieldValueProvider = {
|
|
29
|
+
/**
|
|
30
|
+
* Resolve an editable field config to its simplified type.
|
|
31
|
+
* Returns 'plain' for text fields, 'markup' for rich text/frame fields, null for unsupported.
|
|
32
|
+
*/
|
|
33
|
+
resolveFieldType: (entityType: string, bundle: string, fieldName: string) => FieldValueType | null;
|
|
34
|
+
/**
|
|
35
|
+
* Read the current value of an editable field on a block or entity.
|
|
36
|
+
* Tries the registered getValue() callback first, falls back to DOM element reading.
|
|
37
|
+
*/
|
|
38
|
+
readValue: (entityType: string, uuid: string, bundle: string, fieldName: string, fieldType: FieldValueType) => string;
|
|
39
|
+
/**
|
|
40
|
+
* Read the current value and field type of an editable field.
|
|
41
|
+
*
|
|
42
|
+
* Uses the correct strategy based on the field's configuration:
|
|
43
|
+
* 1. Component editables — use getValue() callback
|
|
44
|
+
* 2. Mutated props — read from mutatedItemProps or mutatedEntity
|
|
45
|
+
* 3. Direct DOM — read innerHTML (markup) or textContent (plain)
|
|
46
|
+
*/
|
|
47
|
+
readFieldValue: (fieldName: string, host: EntityContext) => ReadFieldValueResult | null;
|
|
48
|
+
/**
|
|
49
|
+
* Get all text field values from the page.
|
|
50
|
+
* Tries the adapter method first, falls back to reading from directive system.
|
|
51
|
+
*/
|
|
52
|
+
getTextFieldValues: () => Promise<TextFieldValue[]>;
|
|
53
|
+
};
|
|
54
|
+
export default function fieldValueProvider(adapters: AdaptersProvider, directive: DirectiveProvider, state: StateProvider, types: BlockDefinitionProvider, definitions: DefinitionProvider): FieldValueProvider;
|