@aster-editor/core 0.4.3 → 0.5.0
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/README.md +191 -92
- package/dist/api/commands.d.ts +8 -1
- package/dist/api/commands.d.ts.map +1 -1
- package/dist/api/commands.js +3 -0
- package/dist/api/commands.js.map +1 -1
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +1 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/layout.d.ts +181 -0
- package/dist/api/layout.d.ts.map +1 -0
- package/dist/api/layout.js +28 -0
- package/dist/api/layout.js.map +1 -0
- package/dist/api/options.d.ts +6 -0
- package/dist/api/options.d.ts.map +1 -1
- package/dist/commands/layout.d.ts +40 -0
- package/dist/commands/layout.d.ts.map +1 -0
- package/dist/commands/layout.js +262 -0
- package/dist/commands/layout.js.map +1 -0
- package/dist/commands/standard.d.ts +4 -3
- package/dist/commands/standard.d.ts.map +1 -1
- package/dist/commands/standard.js +7 -3
- package/dist/commands/standard.js.map +1 -1
- package/dist/editor/aster-editor.d.ts +16 -1
- package/dist/editor/aster-editor.d.ts.map +1 -1
- package/dist/editor/aster-editor.js +41 -1
- package/dist/editor/aster-editor.js.map +1 -1
- package/dist/extensions/aster-extensions.d.ts +3 -0
- package/dist/extensions/aster-extensions.d.ts.map +1 -1
- package/dist/extensions/aster-extensions.js +24 -5
- package/dist/extensions/aster-extensions.js.map +1 -1
- package/dist/extensions/header-footer-sanitize.d.ts +22 -0
- package/dist/extensions/header-footer-sanitize.d.ts.map +1 -0
- package/dist/extensions/header-footer-sanitize.js +226 -0
- package/dist/extensions/header-footer-sanitize.js.map +1 -0
- package/dist/extensions/layout-css.d.ts +88 -0
- package/dist/extensions/layout-css.d.ts.map +1 -0
- package/dist/extensions/layout-css.js +297 -0
- package/dist/extensions/layout-css.js.map +1 -0
- package/dist/extensions/list-layout.d.ts +23 -0
- package/dist/extensions/list-layout.d.ts.map +1 -0
- package/dist/extensions/list-layout.js +65 -0
- package/dist/extensions/list-layout.js.map +1 -0
- package/dist/extensions/page-break.d.ts +8 -0
- package/dist/extensions/page-break.d.ts.map +1 -0
- package/dist/extensions/page-break.js +20 -0
- package/dist/extensions/page-break.js.map +1 -0
- package/dist/extensions/page-view.d.ts +68 -0
- package/dist/extensions/page-view.d.ts.map +1 -0
- package/dist/extensions/page-view.js +189 -0
- package/dist/extensions/page-view.js.map +1 -0
- package/dist/extensions/pagination-controller.d.ts +110 -0
- package/dist/extensions/pagination-controller.d.ts.map +1 -0
- package/dist/extensions/pagination-controller.js +295 -0
- package/dist/extensions/pagination-controller.js.map +1 -0
- package/dist/extensions/pagination-layout.d.ts +54 -0
- package/dist/extensions/pagination-layout.d.ts.map +1 -0
- package/dist/extensions/pagination-layout.js +109 -0
- package/dist/extensions/pagination-layout.js.map +1 -0
- package/dist/extensions/pagination-measure.d.ts +42 -0
- package/dist/extensions/pagination-measure.d.ts.map +1 -0
- package/dist/extensions/pagination-measure.js +108 -0
- package/dist/extensions/pagination-measure.js.map +1 -0
- package/dist/extensions/pagination.d.ts +36 -0
- package/dist/extensions/pagination.d.ts.map +1 -0
- package/dist/extensions/pagination.js +69 -0
- package/dist/extensions/pagination.js.map +1 -0
- package/dist/extensions/paragraph-layout.d.ts +62 -0
- package/dist/extensions/paragraph-layout.d.ts.map +1 -0
- package/dist/extensions/paragraph-layout.js +227 -0
- package/dist/extensions/paragraph-layout.js.map +1 -0
- package/dist/extensions/run-layout.d.ts +79 -0
- package/dist/extensions/run-layout.d.ts.map +1 -0
- package/dist/extensions/run-layout.js +302 -0
- package/dist/extensions/run-layout.js.map +1 -0
- package/dist/extensions/table-layout.d.ts +85 -0
- package/dist/extensions/table-layout.d.ts.map +1 -0
- package/dist/extensions/table-layout.js +314 -0
- package/dist/extensions/table-layout.js.map +1 -0
- package/dist/html/serialize-html.d.ts +42 -0
- package/dist/html/serialize-html.d.ts.map +1 -0
- package/dist/html/serialize-html.js +159 -0
- package/dist/html/serialize-html.js.map +1 -0
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +8 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/fr.d.ts.map +1 -1
- package/dist/i18n/fr.js +8 -0
- package/dist/i18n/fr.js.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { sanitizeHeaderFooterHtml } from './header-footer-sanitize';
|
|
2
|
+
import { roundLayoutNumber } from './layout-css';
|
|
3
|
+
// Sanitiseur des en-têtes et pieds : extrait en F30 (R30-13), même API qu'avant.
|
|
4
|
+
export { MAX_SANITIZE_DEPTH, sanitizeHeaderFooterHtml } from './header-footer-sanitize';
|
|
5
|
+
/** Classe posée sur l'hôte de l'éditeur quand la vue page est active. */
|
|
6
|
+
export const PAGE_VIEW_CLASS = 'aster--page-view';
|
|
7
|
+
/** Classe du conteneur d'en-tête rendu avant le corps. */
|
|
8
|
+
export const PAGE_HEADER_CLASS = 'aster-page-header';
|
|
9
|
+
/** Classe du conteneur de pied rendu après le corps. */
|
|
10
|
+
export const PAGE_FOOTER_CLASS = 'aster-page-footer';
|
|
11
|
+
/** Marge par défaut d'un document Word : 1 pouce. */
|
|
12
|
+
export const DEFAULT_PAGE_MARGIN_MM = 25.4;
|
|
13
|
+
/** Distance par défaut du bord à l'en-tête / au pied dans Word : un demi-pouce. */
|
|
14
|
+
export const DEFAULT_HEADER_FOOTER_MARGIN_MM = 12.7;
|
|
15
|
+
/**
|
|
16
|
+
* Borne haute de toute dimension ou marge de page, en millimètres (R23-05). Au-delà (ou
|
|
17
|
+
* pour `1e308`, dont `value * 100` déborde en `Infinity` au formatage), la valeur tombe sur
|
|
18
|
+
* le défaut : aucune variable CSS ne vaut jamais `Infinitymm`.
|
|
19
|
+
*/
|
|
20
|
+
export const MAX_PAGE_MM = 10_000;
|
|
21
|
+
/** Dimensions des formats nommés, en portrait, en millimètres. */
|
|
22
|
+
export const PAGE_SIZES_MM = {
|
|
23
|
+
A3: { widthMm: 297, heightMm: 420 },
|
|
24
|
+
A4: { widthMm: 210, heightMm: 297 },
|
|
25
|
+
A5: { widthMm: 148, heightMm: 210 },
|
|
26
|
+
Letter: { widthMm: 215.9, heightMm: 279.4 },
|
|
27
|
+
Legal: { widthMm: 215.9, heightMm: 355.6 },
|
|
28
|
+
};
|
|
29
|
+
/** Variables CSS posées sur l'hôte, dans l'ordre. */
|
|
30
|
+
export const PAGE_VIEW_CSS_VARIABLES = [
|
|
31
|
+
'--aster-page-width',
|
|
32
|
+
'--aster-page-height',
|
|
33
|
+
'--aster-page-margin-top',
|
|
34
|
+
'--aster-page-margin-right',
|
|
35
|
+
'--aster-page-margin-bottom',
|
|
36
|
+
'--aster-page-margin-left',
|
|
37
|
+
'--aster-page-margin-header',
|
|
38
|
+
'--aster-page-margin-footer',
|
|
39
|
+
];
|
|
40
|
+
/** Formate des millimètres avec au plus deux décimales ; jamais `Infinitymm` ni `NaNmm`. */
|
|
41
|
+
function formatMm(value) {
|
|
42
|
+
const rounded = roundLayoutNumber(value);
|
|
43
|
+
return `${Number.isFinite(rounded) ? rounded : 0}mm`;
|
|
44
|
+
}
|
|
45
|
+
/** Nombre fini strictement positif et au plus `MAX_PAGE_MM`, sinon le repli. */
|
|
46
|
+
function positiveOr(value, fallback) {
|
|
47
|
+
return typeof value === 'number' && Number.isFinite(value) && value > 0 && value <= MAX_PAGE_MM
|
|
48
|
+
? value
|
|
49
|
+
: fallback;
|
|
50
|
+
}
|
|
51
|
+
/** Nombre fini positif ou nul et au plus `MAX_PAGE_MM`, sinon le repli. */
|
|
52
|
+
function nonNegativeOr(value, fallback) {
|
|
53
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0 && value <= MAX_PAGE_MM
|
|
54
|
+
? value
|
|
55
|
+
: fallback;
|
|
56
|
+
}
|
|
57
|
+
/** Vrai si la taille est un format nommé connu. */
|
|
58
|
+
function isPageSizeName(value) {
|
|
59
|
+
return typeof value === 'string' && value in PAGE_SIZES_MM;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Résout les dimensions et marges d'une page depuis `layout.page` : format nommé ou libre
|
|
63
|
+
* (A4 par défaut), orientation paysage qui inverse largeur et hauteur, marges à 25,4 mm
|
|
64
|
+
* par défaut, en-tête et pied à 12,7 mm du bord. Les valeurs absurdes (négatives, `NaN`,
|
|
65
|
+
* infinies, au-delà de `MAX_PAGE_MM`) tombent sur les défauts.
|
|
66
|
+
*/
|
|
67
|
+
export function resolvePageMetrics(layout) {
|
|
68
|
+
const page = layout?.page;
|
|
69
|
+
const size = page?.size;
|
|
70
|
+
let dimensions = PAGE_SIZES_MM.A4;
|
|
71
|
+
if (isPageSizeName(size)) {
|
|
72
|
+
dimensions = PAGE_SIZES_MM[size];
|
|
73
|
+
}
|
|
74
|
+
else if (typeof size === 'object' && size !== null) {
|
|
75
|
+
dimensions = {
|
|
76
|
+
widthMm: positiveOr(size.widthMm, PAGE_SIZES_MM.A4.widthMm),
|
|
77
|
+
heightMm: positiveOr(size.heightMm, PAGE_SIZES_MM.A4.heightMm),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const landscape = page?.orientation === 'landscape';
|
|
81
|
+
const margins = page?.margins;
|
|
82
|
+
return {
|
|
83
|
+
widthMm: landscape ? dimensions.heightMm : dimensions.widthMm,
|
|
84
|
+
heightMm: landscape ? dimensions.widthMm : dimensions.heightMm,
|
|
85
|
+
marginTopMm: nonNegativeOr(margins?.topMm, DEFAULT_PAGE_MARGIN_MM),
|
|
86
|
+
marginRightMm: nonNegativeOr(margins?.rightMm, DEFAULT_PAGE_MARGIN_MM),
|
|
87
|
+
marginBottomMm: nonNegativeOr(margins?.bottomMm, DEFAULT_PAGE_MARGIN_MM),
|
|
88
|
+
marginLeftMm: nonNegativeOr(margins?.leftMm, DEFAULT_PAGE_MARGIN_MM),
|
|
89
|
+
marginHeaderMm: nonNegativeOr(margins?.headerMm, DEFAULT_HEADER_FOOTER_MARGIN_MM),
|
|
90
|
+
marginFooterMm: nonNegativeOr(margins?.footerMm, DEFAULT_HEADER_FOOTER_MARGIN_MM),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/** Valeurs des variables CSS, dans l'ordre de `PAGE_VIEW_CSS_VARIABLES`. */
|
|
94
|
+
export function pageViewCssValues(metrics) {
|
|
95
|
+
return [
|
|
96
|
+
formatMm(metrics.widthMm),
|
|
97
|
+
formatMm(metrics.heightMm),
|
|
98
|
+
formatMm(metrics.marginTopMm),
|
|
99
|
+
formatMm(metrics.marginRightMm),
|
|
100
|
+
formatMm(metrics.marginBottomMm),
|
|
101
|
+
formatMm(metrics.marginLeftMm),
|
|
102
|
+
formatMm(metrics.marginHeaderMm),
|
|
103
|
+
formatMm(metrics.marginFooterMm),
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Événement DOM (sans bulle) émis sur `contentElement` quand la vue page est activée ou
|
|
108
|
+
* retirée. Le plugin de pagination (L30) l'écoute sur `view.dom` et relit
|
|
109
|
+
* `getActivePageView` : aucune dépendance de `page-view` vers le plugin.
|
|
110
|
+
*/
|
|
111
|
+
export const PAGE_VIEW_CHANGE_EVENT = 'aster:page-view-change';
|
|
112
|
+
/** Options de la vue page active, par conteneur de contenu (`view.dom`). */
|
|
113
|
+
const ACTIVE_PAGE_VIEWS = new WeakMap();
|
|
114
|
+
/** Options de la vue page active sur ce conteneur de contenu, `null` si elle est inactive. */
|
|
115
|
+
export function getActivePageView(contentElement) {
|
|
116
|
+
return ACTIVE_PAGE_VIEWS.get(contentElement) ?? null;
|
|
117
|
+
}
|
|
118
|
+
/** Signale un changement de vue page aux plugins qui écoutent `contentElement`. */
|
|
119
|
+
function notifyPageViewChange(contentElement) {
|
|
120
|
+
contentElement.dispatchEvent(new CustomEvent(PAGE_VIEW_CHANGE_EVENT));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Active la vue page : classe `aster--page-view` et variables `--aster-page-*` sur
|
|
124
|
+
* l'hôte, conteneurs `div.aster-page-header` / `div.aster-page-footer` (contenu assaini)
|
|
125
|
+
* juste avant et juste après `contentElement`. La feuille de style est dans `ui` ; le
|
|
126
|
+
* core ne pose que classes, variables et conteneurs.
|
|
127
|
+
*/
|
|
128
|
+
export function applyPageView(host, contentElement, options) {
|
|
129
|
+
const layout = options.layout ?? {};
|
|
130
|
+
// Tout ce qui lit la mise en page (et peut lever sur une entrée hostile) est calculé
|
|
131
|
+
// avant la première mutation de l'hôte : en cas d'exception, rien n'est à moitié posé.
|
|
132
|
+
const showHeadersFooters = options.showHeadersFooters !== false;
|
|
133
|
+
const values = pageViewCssValues(resolvePageMetrics(layout));
|
|
134
|
+
const headerHtml = showHeadersFooters
|
|
135
|
+
? sanitizeHeaderFooterHtml(layout.headers?.default?.html ?? '')
|
|
136
|
+
: '';
|
|
137
|
+
const footerHtml = showHeadersFooters
|
|
138
|
+
? sanitizeHeaderFooterHtml(layout.footers?.default?.html ?? '')
|
|
139
|
+
: '';
|
|
140
|
+
host.classList.add(PAGE_VIEW_CLASS);
|
|
141
|
+
PAGE_VIEW_CSS_VARIABLES.forEach((name, index) => {
|
|
142
|
+
host.style.setProperty(name, values[index] ?? '');
|
|
143
|
+
});
|
|
144
|
+
let header = null;
|
|
145
|
+
let footer = null;
|
|
146
|
+
if (showHeadersFooters) {
|
|
147
|
+
const parent = contentElement.parentNode;
|
|
148
|
+
header = document.createElement('div');
|
|
149
|
+
header.className = PAGE_HEADER_CLASS;
|
|
150
|
+
header.setAttribute('contenteditable', 'false');
|
|
151
|
+
header.innerHTML = headerHtml;
|
|
152
|
+
footer = document.createElement('div');
|
|
153
|
+
footer.className = PAGE_FOOTER_CLASS;
|
|
154
|
+
footer.setAttribute('contenteditable', 'false');
|
|
155
|
+
footer.innerHTML = footerHtml;
|
|
156
|
+
if (parent) {
|
|
157
|
+
parent.insertBefore(header, contentElement);
|
|
158
|
+
parent.insertBefore(footer, contentElement.nextSibling);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Pagination (L30) : les options sont lisibles par le plugin avant qu'il soit prévenu.
|
|
162
|
+
ACTIVE_PAGE_VIEWS.set(contentElement, options);
|
|
163
|
+
notifyPageViewChange(contentElement);
|
|
164
|
+
let removed = false;
|
|
165
|
+
return {
|
|
166
|
+
layout,
|
|
167
|
+
header,
|
|
168
|
+
footer,
|
|
169
|
+
remove() {
|
|
170
|
+
if (removed) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
removed = true;
|
|
174
|
+
// Le plugin de pagination retire d'abord ses propres variables et décorations.
|
|
175
|
+
ACTIVE_PAGE_VIEWS.delete(contentElement);
|
|
176
|
+
notifyPageViewChange(contentElement);
|
|
177
|
+
host.classList.remove(PAGE_VIEW_CLASS);
|
|
178
|
+
for (const name of PAGE_VIEW_CSS_VARIABLES) {
|
|
179
|
+
host.style.removeProperty(name);
|
|
180
|
+
}
|
|
181
|
+
if (host.getAttribute('style') === '') {
|
|
182
|
+
host.removeAttribute('style');
|
|
183
|
+
}
|
|
184
|
+
header?.remove();
|
|
185
|
+
footer?.remove();
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=page-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-view.js","sourceRoot":"","sources":["../../src/extensions/page-view.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,iFAAiF;AACjF,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAExF,yEAAyE;AACzE,MAAM,CAAC,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAClD,0DAA0D;AAC1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AACrD,wDAAwD;AACxD,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAErD,qDAAqD;AACrD,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAE3C,mFAAmF;AACnF,MAAM,CAAC,MAAM,+BAA+B,GAAG,IAAI,CAAC;AAEpD;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC;AAElC,kEAAkE;AAClE,MAAM,CAAC,MAAM,aAAa,GAAmD;IAC3E,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;IACnC,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;IACnC,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;IACnC,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE;IAC3C,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE;CAC3C,CAAC;AAEF,qDAAqD;AACrD,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,oBAAoB;IACpB,qBAAqB;IACrB,yBAAyB;IACzB,2BAA2B;IAC3B,4BAA4B;IAC5B,0BAA0B;IAC1B,4BAA4B;IAC5B,4BAA4B;CACpB,CAAC;AAgBX,4FAA4F;AAC5F,SAAS,QAAQ,CAAC,KAAa;IAC7B,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACzC,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD,CAAC;AAED,gFAAgF;AAChF,SAAS,UAAU,CAAC,KAAyB,EAAE,QAAgB;IAC7D,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,WAAW;QAC7F,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,QAAQ,CAAC;AACf,CAAC;AAED,2EAA2E;AAC3E,SAAS,aAAa,CAAC,KAAyB,EAAE,QAAgB;IAChE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,WAAW;QAC9F,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,QAAQ,CAAC;AACf,CAAC;AAED,mDAAmD;AACnD,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,aAAa,CAAC;AAC7D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAyC;IAC1E,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,CAAC;IAC1B,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,CAAC;IACxB,IAAI,UAAU,GAAmB,aAAa,CAAC,EAAE,CAAC;IAClD,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;SAAM,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACrD,UAAU,GAAG;YACX,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,CAAC,OAAO,CAAC;YAC3D,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE,CAAC,QAAQ,CAAC;SAC/D,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,EAAE,WAAW,KAAK,WAAW,CAAC;IACpD,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,CAAC;IAC9B,OAAO;QACL,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO;QAC7D,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ;QAC9D,WAAW,EAAE,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE,sBAAsB,CAAC;QAClE,aAAa,EAAE,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,sBAAsB,CAAC;QACtE,cAAc,EAAE,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,sBAAsB,CAAC;QACxE,YAAY,EAAE,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,sBAAsB,CAAC;QACpE,cAAc,EAAE,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,+BAA+B,CAAC;QACjF,cAAc,EAAE,aAAa,CAAC,OAAO,EAAE,QAAQ,EAAE,+BAA+B,CAAC;KAClF,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,iBAAiB,CAAC,OAAoB;IACpD,OAAO;QACL,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC;QACzB,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC1B,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC;QAC7B,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC;QAC/B,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC;QAChC,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC;QAC9B,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC;QAChC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC;KACjC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,wBAAwB,CAAC;AAE/D,4EAA4E;AAC5E,MAAM,iBAAiB,GAAG,IAAI,OAAO,EAAgC,CAAC;AAEtE,8FAA8F;AAC9F,MAAM,UAAU,iBAAiB,CAAC,cAA2B;IAC3D,OAAO,iBAAiB,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC;AACvD,CAAC;AAED,mFAAmF;AACnF,SAAS,oBAAoB,CAAC,cAA2B;IACvD,cAAc,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,sBAAsB,CAAC,CAAC,CAAC;AACxE,CAAC;AAWD;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAiB,EACjB,cAA2B,EAC3B,OAAwB;IAExB,MAAM,MAAM,GAAmB,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;IACpD,qFAAqF;IACrF,uFAAuF;IACvF,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,KAAK,KAAK,CAAC;IAChE,MAAM,MAAM,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,kBAAkB;QACnC,CAAC,CAAC,wBAAwB,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;QAC/D,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,UAAU,GAAG,kBAAkB;QACnC,CAAC,CAAC,wBAAwB,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;QAC/D,CAAC,CAAC,EAAE,CAAC;IAEP,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACpC,uBAAuB,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC9C,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,IAAI,MAAM,GAAuB,IAAI,CAAC;IACtC,IAAI,MAAM,GAAuB,IAAI,CAAC;IACtC,IAAI,kBAAkB,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC;QACzC,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,CAAC,SAAS,GAAG,iBAAiB,CAAC;QACrC,MAAM,CAAC,YAAY,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,CAAC,SAAS,GAAG,UAAU,CAAC;QAC9B,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,CAAC,SAAS,GAAG,iBAAiB,CAAC;QACrC,MAAM,CAAC,YAAY,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,CAAC,SAAS,GAAG,UAAU,CAAC;QAC9B,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YAC5C,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,uFAAuF;IACvF,iBAAiB,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAC/C,oBAAoB,CAAC,cAAc,CAAC,CAAC;IAErC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,OAAO;QACL,MAAM;QACN,MAAM;QACN,MAAM;QACN,MAAM;YACJ,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO;YACT,CAAC;YACD,OAAO,GAAG,IAAI,CAAC;YACf,+EAA+E;YAC/E,iBAAiB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YACzC,oBAAoB,CAAC,cAAc,CAAC,CAAC;YACrC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;YACvC,KAAK,MAAM,IAAI,IAAI,uBAAuB,EAAE,CAAC;gBAC3C,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YAClC,CAAC;YACD,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;gBACtC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAChC,CAAC;YACD,MAAM,EAAE,MAAM,EAAE,CAAC;YACjB,MAAM,EAAE,MAAM,EAAE,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { PluginKey, type EditorState, type Transaction } from '@tiptap/pm/state';
|
|
2
|
+
import { DecorationSet, type EditorView } from '@tiptap/pm/view';
|
|
3
|
+
import type { AsterEditor, PageViewOptions } from '../api';
|
|
4
|
+
import { type PaginationResult } from './pagination-layout';
|
|
5
|
+
/**
|
|
6
|
+
* Contrôleur de la pagination approximative (session 3, L30, extrait de `pagination.ts`
|
|
7
|
+
* en F30, R30-13) : vue du plugin ProseMirror qui écoute l'activation de la vue page,
|
|
8
|
+
* planifie les mesures, observe la largeur de la feuille et dessine les coupures en
|
|
9
|
+
* décorations widget. Le jeu de décorations vit dans l'état du plugin, mappé par
|
|
10
|
+
* ProseMirror à chaque transaction (R30-05) ; il n'est reconstruit qu'après une mesure.
|
|
11
|
+
*/
|
|
12
|
+
/** Classe du libellé « Page n / N » rendu dans la coupure. */
|
|
13
|
+
export declare const PAGE_GAP_NUMBER_CLASS = "aster-page-gap__number";
|
|
14
|
+
/** Attribut du widget : numéro (1-based) de la page qui commence après la coupure. */
|
|
15
|
+
export declare const PAGE_NUMBER_ATTRIBUTE = "data-page-number";
|
|
16
|
+
/** Attribut du widget et du pied affiché : nombre total de pages. */
|
|
17
|
+
export declare const PAGE_COUNT_ATTRIBUTE = "data-page-count";
|
|
18
|
+
/** Variable CSS posée sur l'hôte : nombre de pages, pour étirer la feuille (`ui/themes/page.css`). */
|
|
19
|
+
export declare const PAGE_COUNT_CSS_VARIABLE = "--aster-page-count";
|
|
20
|
+
/** Variable CSS posée sur chaque widget : espace libre en bas de la page précédente (px). */
|
|
21
|
+
export declare const PAGE_GAP_FILL_CSS_VARIABLE = "--aster-page-gap-fill";
|
|
22
|
+
/** Délai de débounce après une modification du document, en millisecondes. */
|
|
23
|
+
export declare const PAGINATION_DEBOUNCE_MS = 150;
|
|
24
|
+
/**
|
|
25
|
+
* État du plugin : le jeu de décorations courant et la génération du contrôleur qui l'a
|
|
26
|
+
* construit. ProseMirror le mappe (`DecorationSet.map`) à chaque transaction qui change le
|
|
27
|
+
* document : une frappe ne reconstruit rien (R30-05). Après une mesure, le contrôleur
|
|
28
|
+
* avance sa génération et le jeu est reconstruit **en place** à la lecture suivante, sans
|
|
29
|
+
* transaction (même état, nouveau jeu) : l'objet est mutable à dessein.
|
|
30
|
+
*/
|
|
31
|
+
export interface PaginationDecorations {
|
|
32
|
+
generation: number;
|
|
33
|
+
set: DecorationSet;
|
|
34
|
+
}
|
|
35
|
+
/** Clé du plugin ProseMirror ; son état est le jeu de décorations (`PaginationDecorations`). */
|
|
36
|
+
export declare const paginationPluginKey: PluginKey<PaginationDecorations>;
|
|
37
|
+
/** État initial du plugin : génération 0, toujours en retard sur le contrôleur (qui part à 1). */
|
|
38
|
+
export declare function initPaginationDecorations(): PaginationDecorations;
|
|
39
|
+
/** Une transaction qui change le document mappe le jeu ; les autres le partagent tel quel. */
|
|
40
|
+
export declare function mapPaginationDecorations(tr: Transaction, value: PaginationDecorations): PaginationDecorations;
|
|
41
|
+
/**
|
|
42
|
+
* Proposition de contrat (`api/layout.ts`, non modifié ici) : `PageViewOptions.pagination`,
|
|
43
|
+
* vrai par défaut quand la vue page est active. Le plugin lit la propriété si elle est
|
|
44
|
+
* présente ; `ui` l'envoie depuis le dialogue « Mise en page ».
|
|
45
|
+
*/
|
|
46
|
+
export interface PaginatedPageViewOptions extends PageViewOptions {
|
|
47
|
+
readonly pagination?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Vrai sauf si les options portent explicitement `pagination: false`. `null` / `undefined`
|
|
51
|
+
* (pas d'options connues) vaut le défaut, vrai ; l'activité de la vue page elle-même est
|
|
52
|
+
* vérifiée à part.
|
|
53
|
+
*/
|
|
54
|
+
export declare function isPaginationEnabled(options: PageViewOptions | null | undefined): boolean;
|
|
55
|
+
/** Contrôleur attaché à une vue, `null` sans extension `Pagination` ou vue détruite. */
|
|
56
|
+
export declare function paginationControllerOf(view: EditorView): PaginationController | null;
|
|
57
|
+
/**
|
|
58
|
+
* Vue du plugin : écoute l'activation de la vue page, planifie les mesures (débounce
|
|
59
|
+
* puis `requestAnimationFrame`, jamais dans un `dispatch`), observe le redimensionnement
|
|
60
|
+
* de la feuille, et redessine les décorations sans transaction (`view.updateState` sur
|
|
61
|
+
* l'état courant : le document ne change pas, aucun `change` n'est émis).
|
|
62
|
+
*/
|
|
63
|
+
export declare class PaginationController {
|
|
64
|
+
private readonly view;
|
|
65
|
+
private readonly aster;
|
|
66
|
+
result: PaginationResult;
|
|
67
|
+
private options;
|
|
68
|
+
private host;
|
|
69
|
+
/** Génération du rendu : avance à chaque mesure qui change quelque chose, locale ou arrêt. */
|
|
70
|
+
private generation;
|
|
71
|
+
/** Document pour lequel le jeu a été construit en dernier (`null` : jamais). */
|
|
72
|
+
private builtDoc;
|
|
73
|
+
private cancelPending;
|
|
74
|
+
private observer;
|
|
75
|
+
private observedWidth;
|
|
76
|
+
private readonly unsubscribeLocale;
|
|
77
|
+
private readonly onPageViewChange;
|
|
78
|
+
private destroyed;
|
|
79
|
+
constructor(view: EditorView, aster: AsterEditor | null);
|
|
80
|
+
/** Appelé par ProseMirror après chaque transaction : une modification relance une mesure débouncée. */
|
|
81
|
+
update(view: EditorView, prevState: EditorState): void;
|
|
82
|
+
destroy(): void;
|
|
83
|
+
/**
|
|
84
|
+
* Décorations pour l'état donné : le jeu porté par l'état (mappé par ProseMirror depuis
|
|
85
|
+
* sa construction), reconstruit en place seulement si sa génération est en retard
|
|
86
|
+
* (mesure, locale ou arrêt depuis). Vide hors vue page ou sans coupure.
|
|
87
|
+
*/
|
|
88
|
+
decorationsFor(state: EditorState): DecorationSet;
|
|
89
|
+
/** Mesure immédiate (tests, intégrateur) ; `EMPTY_PAGINATION` si inactif. */
|
|
90
|
+
measureNow(): PaginationResult;
|
|
91
|
+
/** Relit la vue page active : démarre, remesure ou arrête la pagination. */
|
|
92
|
+
private syncActivation;
|
|
93
|
+
/** `ResizeObserver` absent en jsdom et en SSR : garde, la frappe suffit alors à remesurer. */
|
|
94
|
+
private ensureObserver;
|
|
95
|
+
/** Débounce (`delay` ms) puis frame d'animation ; une nouvelle demande annule la précédente. */
|
|
96
|
+
private schedule;
|
|
97
|
+
/**
|
|
98
|
+
* Mesure, puis reconstruit le jeu si les coupures ont changé ou si le document a bougé
|
|
99
|
+
* depuis la dernière construction (le jeu mappé suit ses blocs, pas les index mesurés).
|
|
100
|
+
*/
|
|
101
|
+
private measureAndApply;
|
|
102
|
+
/** Phase d'écriture : variable sur l'hôte et attribut du pied affiché. */
|
|
103
|
+
private writePageCount;
|
|
104
|
+
/** Pied affiché posé par la vue page : frère de `view.dom`. */
|
|
105
|
+
private footer;
|
|
106
|
+
private deactivate;
|
|
107
|
+
/** Redessine sans transaction : génération avancée, même état, le jeu est reconstruit à la lecture. */
|
|
108
|
+
private redraw;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=pagination-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination-controller.d.ts","sourceRoot":"","sources":["../../src/extensions/pagination-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { PluginKey } from '@tiptap/pm/state';
|
|
2
|
+
import { Decoration, DecorationSet } from '@tiptap/pm/view';
|
|
3
|
+
import { PAGE_FOOTER_CLASS, PAGE_VIEW_CHANGE_EVENT, PAGE_VIEW_CLASS, getActivePageView, } from './page-view';
|
|
4
|
+
import { EMPTY_PAGINATION, samePagination, } from './pagination-layout';
|
|
5
|
+
import { PAGE_GAP_CLASS, measurePagination } from './pagination-measure';
|
|
6
|
+
/**
|
|
7
|
+
* Contrôleur de la pagination approximative (session 3, L30, extrait de `pagination.ts`
|
|
8
|
+
* en F30, R30-13) : vue du plugin ProseMirror qui écoute l'activation de la vue page,
|
|
9
|
+
* planifie les mesures, observe la largeur de la feuille et dessine les coupures en
|
|
10
|
+
* décorations widget. Le jeu de décorations vit dans l'état du plugin, mappé par
|
|
11
|
+
* ProseMirror à chaque transaction (R30-05) ; il n'est reconstruit qu'après une mesure.
|
|
12
|
+
*/
|
|
13
|
+
/** Classe du libellé « Page n / N » rendu dans la coupure. */
|
|
14
|
+
export const PAGE_GAP_NUMBER_CLASS = 'aster-page-gap__number';
|
|
15
|
+
/** Attribut du widget : numéro (1-based) de la page qui commence après la coupure. */
|
|
16
|
+
export const PAGE_NUMBER_ATTRIBUTE = 'data-page-number';
|
|
17
|
+
/** Attribut du widget et du pied affiché : nombre total de pages. */
|
|
18
|
+
export const PAGE_COUNT_ATTRIBUTE = 'data-page-count';
|
|
19
|
+
/** Variable CSS posée sur l'hôte : nombre de pages, pour étirer la feuille (`ui/themes/page.css`). */
|
|
20
|
+
export const PAGE_COUNT_CSS_VARIABLE = '--aster-page-count';
|
|
21
|
+
/** Variable CSS posée sur chaque widget : espace libre en bas de la page précédente (px). */
|
|
22
|
+
export const PAGE_GAP_FILL_CSS_VARIABLE = '--aster-page-gap-fill';
|
|
23
|
+
/** Délai de débounce après une modification du document, en millisecondes. */
|
|
24
|
+
export const PAGINATION_DEBOUNCE_MS = 150;
|
|
25
|
+
/** Clé du plugin ProseMirror ; son état est le jeu de décorations (`PaginationDecorations`). */
|
|
26
|
+
export const paginationPluginKey = new PluginKey('asterPagination');
|
|
27
|
+
/** État initial du plugin : génération 0, toujours en retard sur le contrôleur (qui part à 1). */
|
|
28
|
+
export function initPaginationDecorations() {
|
|
29
|
+
return { generation: 0, set: DecorationSet.empty };
|
|
30
|
+
}
|
|
31
|
+
/** Une transaction qui change le document mappe le jeu ; les autres le partagent tel quel. */
|
|
32
|
+
export function mapPaginationDecorations(tr, value) {
|
|
33
|
+
if (!tr.docChanged) {
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
return { generation: value.generation, set: value.set.map(tr.mapping, tr.doc) };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Vrai sauf si les options portent explicitement `pagination: false`. `null` / `undefined`
|
|
40
|
+
* (pas d'options connues) vaut le défaut, vrai ; l'activité de la vue page elle-même est
|
|
41
|
+
* vérifiée à part.
|
|
42
|
+
*/
|
|
43
|
+
export function isPaginationEnabled(options) {
|
|
44
|
+
if (typeof options !== 'object' || options === null) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return options.pagination !== false;
|
|
48
|
+
}
|
|
49
|
+
/** Libellé « Page n / N » : i18n du core (`pageView.page`, `pageView.of`), repli sans éditeur. */
|
|
50
|
+
function pageLabel(aster, page, count) {
|
|
51
|
+
if (!aster) {
|
|
52
|
+
return `Page ${page} / ${count}`;
|
|
53
|
+
}
|
|
54
|
+
return `${aster.i18n.t('pageView.page')} ${page} ${aster.i18n.t('pageView.of')} ${count}`;
|
|
55
|
+
}
|
|
56
|
+
/** DOM d'une coupure : `div.aster-page-gap[data-page-number][data-page-count]` et son libellé. */
|
|
57
|
+
function renderGap(gap, count, label) {
|
|
58
|
+
const element = document.createElement('div');
|
|
59
|
+
element.className = PAGE_GAP_CLASS;
|
|
60
|
+
element.setAttribute('contenteditable', 'false');
|
|
61
|
+
element.setAttribute('aria-hidden', 'true');
|
|
62
|
+
element.setAttribute(PAGE_NUMBER_ATTRIBUTE, String(gap.page));
|
|
63
|
+
element.setAttribute(PAGE_COUNT_ATTRIBUTE, String(count));
|
|
64
|
+
element.style.setProperty(PAGE_GAP_FILL_CSS_VARIABLE, `${Math.round(gap.fill)}px`);
|
|
65
|
+
const number = document.createElement('span');
|
|
66
|
+
number.className = PAGE_GAP_NUMBER_CLASS;
|
|
67
|
+
number.textContent = label;
|
|
68
|
+
element.append(number);
|
|
69
|
+
return element;
|
|
70
|
+
}
|
|
71
|
+
/** Jeu de décorations widget : une coupure avant chaque bloc d'index listé, clé stable par rendu. */
|
|
72
|
+
function buildDecorations(doc, result, locale, aster) {
|
|
73
|
+
if (result.gaps.length === 0) {
|
|
74
|
+
return DecorationSet.empty;
|
|
75
|
+
}
|
|
76
|
+
const byIndex = new Map();
|
|
77
|
+
for (const gap of result.gaps) {
|
|
78
|
+
byIndex.set(gap.index, gap);
|
|
79
|
+
}
|
|
80
|
+
const decorations = [];
|
|
81
|
+
doc.forEach((_node, offset, index) => {
|
|
82
|
+
const gap = byIndex.get(index);
|
|
83
|
+
if (!gap) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const label = pageLabel(aster, gap.page, result.pageCount);
|
|
87
|
+
decorations.push(Decoration.widget(offset, () => renderGap(gap, result.pageCount, label), {
|
|
88
|
+
side: -1,
|
|
89
|
+
// La clé porte tout ce qui change le rendu : ProseMirror réutilise le DOM à clé égale.
|
|
90
|
+
key: `${PAGE_GAP_CLASS}:${locale}:${gap.page}:${result.pageCount}:${Math.round(gap.fill)}`,
|
|
91
|
+
ignoreSelection: true,
|
|
92
|
+
}));
|
|
93
|
+
});
|
|
94
|
+
return DecorationSet.create(doc, decorations);
|
|
95
|
+
}
|
|
96
|
+
/** Contrôleur par vue ProseMirror, pour `getPaginationResult` et `paginateNow`. */
|
|
97
|
+
const CONTROLLERS = new WeakMap();
|
|
98
|
+
/** Contrôleur attaché à une vue, `null` sans extension `Pagination` ou vue détruite. */
|
|
99
|
+
export function paginationControllerOf(view) {
|
|
100
|
+
return CONTROLLERS.get(view) ?? null;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Vue du plugin : écoute l'activation de la vue page, planifie les mesures (débounce
|
|
104
|
+
* puis `requestAnimationFrame`, jamais dans un `dispatch`), observe le redimensionnement
|
|
105
|
+
* de la feuille, et redessine les décorations sans transaction (`view.updateState` sur
|
|
106
|
+
* l'état courant : le document ne change pas, aucun `change` n'est émis).
|
|
107
|
+
*/
|
|
108
|
+
export class PaginationController {
|
|
109
|
+
view;
|
|
110
|
+
aster;
|
|
111
|
+
result = EMPTY_PAGINATION;
|
|
112
|
+
options = null;
|
|
113
|
+
host = null;
|
|
114
|
+
/** Génération du rendu : avance à chaque mesure qui change quelque chose, locale ou arrêt. */
|
|
115
|
+
generation = 1;
|
|
116
|
+
/** Document pour lequel le jeu a été construit en dernier (`null` : jamais). */
|
|
117
|
+
builtDoc = null;
|
|
118
|
+
cancelPending = null;
|
|
119
|
+
observer = null;
|
|
120
|
+
observedWidth = null;
|
|
121
|
+
unsubscribeLocale;
|
|
122
|
+
onPageViewChange = () => this.syncActivation();
|
|
123
|
+
destroyed = false;
|
|
124
|
+
constructor(view, aster) {
|
|
125
|
+
this.view = view;
|
|
126
|
+
this.aster = aster;
|
|
127
|
+
CONTROLLERS.set(view, this);
|
|
128
|
+
view.dom.addEventListener(PAGE_VIEW_CHANGE_EVENT, this.onPageViewChange);
|
|
129
|
+
this.unsubscribeLocale = aster?.on('localeChange', () => this.redraw()) ?? null;
|
|
130
|
+
this.syncActivation();
|
|
131
|
+
}
|
|
132
|
+
/** Appelé par ProseMirror après chaque transaction : une modification relance une mesure débouncée. */
|
|
133
|
+
update(view, prevState) {
|
|
134
|
+
if (this.options !== null && view.state.doc !== prevState.doc) {
|
|
135
|
+
this.schedule(PAGINATION_DEBOUNCE_MS);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
destroy() {
|
|
139
|
+
this.destroyed = true;
|
|
140
|
+
this.cancelPending?.();
|
|
141
|
+
this.cancelPending = null;
|
|
142
|
+
this.observer?.disconnect();
|
|
143
|
+
this.observer = null;
|
|
144
|
+
this.view.dom.removeEventListener(PAGE_VIEW_CHANGE_EVENT, this.onPageViewChange);
|
|
145
|
+
this.unsubscribeLocale?.();
|
|
146
|
+
if (CONTROLLERS.get(this.view) === this) {
|
|
147
|
+
CONTROLLERS.delete(this.view);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Décorations pour l'état donné : le jeu porté par l'état (mappé par ProseMirror depuis
|
|
152
|
+
* sa construction), reconstruit en place seulement si sa génération est en retard
|
|
153
|
+
* (mesure, locale ou arrêt depuis). Vide hors vue page ou sans coupure.
|
|
154
|
+
*/
|
|
155
|
+
decorationsFor(state) {
|
|
156
|
+
const holder = paginationPluginKey.getState(state);
|
|
157
|
+
if (!holder) {
|
|
158
|
+
return DecorationSet.empty;
|
|
159
|
+
}
|
|
160
|
+
if (holder.generation !== this.generation) {
|
|
161
|
+
const locale = this.aster?.i18n.getLocale() ?? '';
|
|
162
|
+
holder.set =
|
|
163
|
+
this.options === null
|
|
164
|
+
? DecorationSet.empty
|
|
165
|
+
: buildDecorations(state.doc, this.result, locale, this.aster);
|
|
166
|
+
holder.generation = this.generation;
|
|
167
|
+
this.builtDoc = state.doc;
|
|
168
|
+
}
|
|
169
|
+
return holder.set;
|
|
170
|
+
}
|
|
171
|
+
/** Mesure immédiate (tests, intégrateur) ; `EMPTY_PAGINATION` si inactif. */
|
|
172
|
+
measureNow() {
|
|
173
|
+
this.cancelPending?.();
|
|
174
|
+
this.cancelPending = null;
|
|
175
|
+
this.measureAndApply();
|
|
176
|
+
return this.result;
|
|
177
|
+
}
|
|
178
|
+
/** Relit la vue page active : démarre, remesure ou arrête la pagination. */
|
|
179
|
+
syncActivation() {
|
|
180
|
+
const options = getActivePageView(this.view.dom);
|
|
181
|
+
if (options === null || !isPaginationEnabled(options)) {
|
|
182
|
+
this.deactivate();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
this.options = options;
|
|
186
|
+
this.host = this.view.dom.closest(`.${PAGE_VIEW_CLASS}`);
|
|
187
|
+
this.ensureObserver();
|
|
188
|
+
this.schedule(0);
|
|
189
|
+
}
|
|
190
|
+
/** `ResizeObserver` absent en jsdom et en SSR : garde, la frappe suffit alors à remesurer. */
|
|
191
|
+
ensureObserver() {
|
|
192
|
+
if (this.observer || typeof ResizeObserver !== 'function') {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
this.observer = new ResizeObserver((entries) => {
|
|
196
|
+
const width = entries[entries.length - 1]?.contentRect.width;
|
|
197
|
+
if (width === undefined) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
// Seule la largeur compte : la hauteur de la feuille bouge à chaque frappe et à chaque coupure posée.
|
|
201
|
+
if (this.observedWidth !== null && width !== this.observedWidth && this.options !== null) {
|
|
202
|
+
this.schedule(PAGINATION_DEBOUNCE_MS);
|
|
203
|
+
}
|
|
204
|
+
this.observedWidth = width;
|
|
205
|
+
});
|
|
206
|
+
this.observer.observe(this.view.dom);
|
|
207
|
+
}
|
|
208
|
+
/** Débounce (`delay` ms) puis frame d'animation ; une nouvelle demande annule la précédente. */
|
|
209
|
+
schedule(delay) {
|
|
210
|
+
this.cancelPending?.();
|
|
211
|
+
const frame = () => {
|
|
212
|
+
if (typeof requestAnimationFrame === 'function') {
|
|
213
|
+
const id = requestAnimationFrame(() => {
|
|
214
|
+
this.cancelPending = null;
|
|
215
|
+
this.measureAndApply();
|
|
216
|
+
});
|
|
217
|
+
this.cancelPending = () => cancelAnimationFrame(id);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
const id = setTimeout(() => {
|
|
221
|
+
this.cancelPending = null;
|
|
222
|
+
this.measureAndApply();
|
|
223
|
+
}, 0);
|
|
224
|
+
this.cancelPending = () => clearTimeout(id);
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
if (delay <= 0) {
|
|
228
|
+
frame();
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const id = setTimeout(frame, delay);
|
|
232
|
+
this.cancelPending = () => clearTimeout(id);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Mesure, puis reconstruit le jeu si les coupures ont changé ou si le document a bougé
|
|
236
|
+
* depuis la dernière construction (le jeu mappé suit ses blocs, pas les index mesurés).
|
|
237
|
+
*/
|
|
238
|
+
measureAndApply() {
|
|
239
|
+
if (this.destroyed || this.options === null || this.view.isDestroyed) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (!this.view.dom.isConnected) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const result = measurePagination(this.view, this.options);
|
|
246
|
+
const changed = !samePagination(result, this.result);
|
|
247
|
+
this.result = result;
|
|
248
|
+
this.writePageCount(result.pageCount);
|
|
249
|
+
const drifted = result.gaps.length > 0 && this.builtDoc !== this.view.state.doc;
|
|
250
|
+
if (changed || drifted) {
|
|
251
|
+
this.redraw();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/** Phase d'écriture : variable sur l'hôte et attribut du pied affiché. */
|
|
255
|
+
writePageCount(count) {
|
|
256
|
+
this.host?.style.setProperty(PAGE_COUNT_CSS_VARIABLE, String(count));
|
|
257
|
+
this.footer()?.setAttribute(PAGE_COUNT_ATTRIBUTE, String(count));
|
|
258
|
+
}
|
|
259
|
+
/** Pied affiché posé par la vue page : frère de `view.dom`. */
|
|
260
|
+
footer() {
|
|
261
|
+
const siblings = this.view.dom.parentElement?.children;
|
|
262
|
+
if (!siblings) {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
return (Array.from(siblings).find((child) => child.classList.contains(PAGE_FOOTER_CLASS)) ?? null);
|
|
266
|
+
}
|
|
267
|
+
deactivate() {
|
|
268
|
+
this.cancelPending?.();
|
|
269
|
+
this.cancelPending = null;
|
|
270
|
+
this.options = null;
|
|
271
|
+
const host = this.host;
|
|
272
|
+
this.host = null;
|
|
273
|
+
if (host) {
|
|
274
|
+
host.style.removeProperty(PAGE_COUNT_CSS_VARIABLE);
|
|
275
|
+
if (host.getAttribute('style') === '') {
|
|
276
|
+
host.removeAttribute('style');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
this.footer()?.removeAttribute(PAGE_COUNT_ATTRIBUTE);
|
|
280
|
+
const hadGaps = this.result.gaps.length > 0;
|
|
281
|
+
this.result = EMPTY_PAGINATION;
|
|
282
|
+
if (hadGaps) {
|
|
283
|
+
this.redraw();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/** Redessine sans transaction : génération avancée, même état, le jeu est reconstruit à la lecture. */
|
|
287
|
+
redraw() {
|
|
288
|
+
if (this.destroyed || this.view.isDestroyed || this.aster?.isDestroyed()) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
this.generation += 1;
|
|
292
|
+
this.view.updateState(this.view.state);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=pagination-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination-controller.js","sourceRoot":"","sources":["../../src/extensions/pagination-controller.ts"],"names":[],"mappings":"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"}
|