@sametalmdr/word-editor 0.0.0-stage → 0.3.0-alpha
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/CHANGELOG.md +108 -0
- package/LICENSE +21 -0
- package/README.md +285 -2
- package/dist/canvas/box-clipboard.d.ts +125 -0
- package/dist/canvas/box-clipboard.js +238 -0
- package/dist/canvas/box-selection.d.ts +36 -0
- package/dist/canvas/box-selection.js +80 -0
- package/dist/canvas/canvas-editor.d.ts +251 -0
- package/dist/canvas/canvas-editor.js +502 -0
- package/dist/canvas/controller.d.ts +243 -0
- package/dist/canvas/controller.js +717 -0
- package/dist/canvas/geometry.d.ts +100 -0
- package/dist/canvas/geometry.js +131 -0
- package/dist/canvas/gesture.d.ts +198 -0
- package/dist/canvas/gesture.js +289 -0
- package/dist/canvas/handles.d.ts +119 -0
- package/dist/canvas/handles.js +212 -0
- package/dist/canvas/hit-test.d.ts +47 -0
- package/dist/canvas/hit-test.js +117 -0
- package/dist/canvas/menu.d.ts +62 -0
- package/dist/canvas/menu.js +82 -0
- package/dist/canvas/mode-controller.d.ts +41 -0
- package/dist/canvas/mode-controller.js +81 -0
- package/dist/canvas/nudge.d.ts +88 -0
- package/dist/canvas/nudge.js +108 -0
- package/dist/canvas/overlay.d.ts +86 -0
- package/dist/canvas/overlay.js +149 -0
- package/dist/canvas/page.d.ts +60 -0
- package/dist/canvas/page.js +83 -0
- package/dist/canvas/resize.d.ts +72 -0
- package/dist/canvas/resize.js +138 -0
- package/dist/canvas/snap.d.ts +62 -0
- package/dist/canvas/snap.js +132 -0
- package/dist/canvas/viewport.d.ts +99 -0
- package/dist/canvas/viewport.js +112 -0
- package/dist/canvas/z-order.d.ts +22 -0
- package/dist/canvas/z-order.js +171 -0
- package/dist/commands/alignment.d.ts +49 -0
- package/dist/commands/alignment.js +150 -0
- package/dist/commands/box.d.ts +111 -0
- package/dist/commands/box.js +272 -0
- package/dist/commands/clipboard.d.ts +30 -0
- package/dist/commands/clipboard.js +93 -0
- package/dist/commands/graphemes.d.ts +28 -0
- package/dist/commands/graphemes.js +112 -0
- package/dist/commands/marks.d.ts +43 -0
- package/dist/commands/marks.js +153 -0
- package/dist/commands/paragraph-props.d.ts +54 -0
- package/dist/commands/paragraph-props.js +176 -0
- package/dist/commands/size.d.ts +96 -0
- package/dist/commands/size.js +368 -0
- package/dist/commands/text.d.ts +95 -0
- package/dist/commands/text.js +291 -0
- package/dist/dev.d.ts +40 -0
- package/dist/dev.js +73 -0
- package/dist/docx.d.ts +4 -0
- package/dist/docx.js +15 -0
- package/dist/editor/editing-host.d.ts +255 -0
- package/dist/editor/editing-host.js +434 -0
- package/dist/element.d.ts +13 -0
- package/dist/element.js +41 -0
- package/dist/fonts/OFL-Carlito.txt +94 -0
- package/dist/fonts/calibri-metrics.d.ts +27 -0
- package/dist/fonts/calibri-metrics.js +88 -0
- package/dist/history/history.d.ts +162 -0
- package/dist/history/history.js +433 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +63 -0
- package/dist/input/beforeinput.d.ts +41 -0
- package/dist/input/beforeinput.js +224 -0
- package/dist/input/clipboard.d.ts +65 -0
- package/dist/input/clipboard.js +107 -0
- package/dist/input/composition.d.ts +184 -0
- package/dist/input/composition.js +341 -0
- package/dist/input/keymap.d.ts +38 -0
- package/dist/input/keymap.js +54 -0
- package/dist/io/json/document-json.d.ts +34 -0
- package/dist/io/json/document-json.js +341 -0
- package/dist/io/ooxml/custgeom.d.ts +25 -0
- package/dist/io/ooxml/custgeom.js +72 -0
- package/dist/io/ooxml/drawingml.d.ts +127 -0
- package/dist/io/ooxml/drawingml.js +232 -0
- package/dist/io/ooxml/edits.d.ts +31 -0
- package/dist/io/ooxml/edits.js +67 -0
- package/dist/io/ooxml/export-splice.d.ts +43 -0
- package/dist/io/ooxml/export-splice.js +880 -0
- package/dist/io/ooxml/export.d.ts +226 -0
- package/dist/io/ooxml/export.js +365 -0
- package/dist/io/ooxml/fill.d.ts +317 -0
- package/dist/io/ooxml/fill.js +618 -0
- package/dist/io/ooxml/fit.d.ts +252 -0
- package/dist/io/ooxml/fit.js +598 -0
- package/dist/io/ooxml/import-gate.d.ts +112 -0
- package/dist/io/ooxml/import-gate.js +200 -0
- package/dist/io/ooxml/import.d.ts +154 -0
- package/dist/io/ooxml/import.js +691 -0
- package/dist/io/ooxml/inflate.d.ts +20 -0
- package/dist/io/ooxml/inflate.js +126 -0
- package/dist/io/ooxml/media.d.ts +12 -0
- package/dist/io/ooxml/media.js +87 -0
- package/dist/io/ooxml/ns.d.ts +12 -0
- package/dist/io/ooxml/ns.js +26 -0
- package/dist/io/ooxml/numbering.d.ts +47 -0
- package/dist/io/ooxml/numbering.js +290 -0
- package/dist/io/ooxml/opc-write.d.ts +12 -0
- package/dist/io/ooxml/opc-write.js +171 -0
- package/dist/io/ooxml/provenance.d.ts +118 -0
- package/dist/io/ooxml/provenance.js +93 -0
- package/dist/io/ooxml/recipe.d.ts +173 -0
- package/dist/io/ooxml/recipe.js +708 -0
- package/dist/io/ooxml/relationships.d.ts +10 -0
- package/dist/io/ooxml/relationships.js +59 -0
- package/dist/io/ooxml/run-fonts.d.ts +89 -0
- package/dist/io/ooxml/run-fonts.js +378 -0
- package/dist/io/ooxml/sections.d.ts +36 -0
- package/dist/io/ooxml/sections.js +107 -0
- package/dist/io/ooxml/slots.d.ts +137 -0
- package/dist/io/ooxml/slots.js +582 -0
- package/dist/io/ooxml/styles-resolve.d.ts +102 -0
- package/dist/io/ooxml/styles-resolve.js +257 -0
- package/dist/io/ooxml/units.d.ts +29 -0
- package/dist/io/ooxml/units.js +43 -0
- package/dist/io/ooxml/value.d.ts +43 -0
- package/dist/io/ooxml/value.js +120 -0
- package/dist/io/ooxml/xml-scan.d.ts +170 -0
- package/dist/io/ooxml/xml-scan.js +616 -0
- package/dist/io/ooxml/zip-container.d.ts +63 -0
- package/dist/io/ooxml/zip-container.js +228 -0
- package/dist/io/ooxml/zip-reject.d.ts +48 -0
- package/dist/io/ooxml/zip-reject.js +106 -0
- package/dist/measure/bleed.d.ts +25 -0
- package/dist/measure/bleed.js +86 -0
- package/dist/measure/controller.d.ts +174 -0
- package/dist/measure/controller.js +460 -0
- package/dist/measure/dirty.d.ts +119 -0
- package/dist/measure/dirty.js +146 -0
- package/dist/measure/extent.d.ts +85 -0
- package/dist/measure/extent.js +157 -0
- package/dist/measure/page-bounds.d.ts +50 -0
- package/dist/measure/page-bounds.js +62 -0
- package/dist/measure/placement.d.ts +39 -0
- package/dist/measure/placement.js +83 -0
- package/dist/measure/probe.d.ts +67 -0
- package/dist/measure/probe.js +84 -0
- package/dist/measure/report.d.ts +53 -0
- package/dist/measure/report.js +75 -0
- package/dist/model/ids.d.ts +39 -0
- package/dist/model/ids.js +70 -0
- package/dist/model/node.d.ts +933 -0
- package/dist/model/node.js +898 -0
- package/dist/model/normalize.d.ts +38 -0
- package/dist/model/normalize.js +146 -0
- package/dist/model/position.d.ts +209 -0
- package/dist/model/position.js +283 -0
- package/dist/model/runs.d.ts +171 -0
- package/dist/model/runs.js +383 -0
- package/dist/model/step-apply.d.ts +34 -0
- package/dist/model/step-apply.js +563 -0
- package/dist/model/step-invert.d.ts +32 -0
- package/dist/model/step-invert.js +397 -0
- package/dist/model/step-map.d.ts +49 -0
- package/dist/model/step-map.js +222 -0
- package/dist/model/step.d.ts +360 -0
- package/dist/model/step.js +258 -0
- package/dist/model/transaction.d.ts +195 -0
- package/dist/model/transaction.js +209 -0
- package/dist/platform/capabilities.d.ts +21 -0
- package/dist/platform/capabilities.js +25 -0
- package/dist/react/index.d.ts +6 -0
- package/dist/react/index.js +21 -0
- package/dist/render/dom.d.ts +226 -0
- package/dist/render/dom.js +676 -0
- package/dist/render/renderer.d.ts +354 -0
- package/dist/render/renderer.js +1003 -0
- package/dist/selection/controller.d.ts +209 -0
- package/dist/selection/controller.js +315 -0
- package/dist/selection/dom-map.d.ts +119 -0
- package/dist/selection/dom-map.js +334 -0
- package/dist/state/editor-state.d.ts +79 -0
- package/dist/state/editor-state.js +109 -0
- package/dist/styles.css +66 -0
- package/package.json +92 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Değişiklik günlüğü
|
|
2
|
+
|
|
3
|
+
## 0.3.0-alpha — 2026-10-26 (yayını sahip yapar)
|
|
4
|
+
|
|
5
|
+
### Eklenenler
|
|
6
|
+
|
|
7
|
+
- **`checkFit(bytes, data, {expectedTags?, multiline?, capacity?})`** — `/docx`'ten
|
|
8
|
+
([ADR-0042](./docs/adr/0042-dom-free-fit-check.md)).
|
|
9
|
+
- **Ne yapar:** doldurmadan önce her değerin satırını şablonun kendi kutusuyla karşılaştırır. Tarayıcı
|
|
10
|
+
gerekmez.
|
|
11
|
+
- **Durumlar:** `fits`, `overflows`, `unknown` ya da `empty`; en dar satırın genişliği, yeri ve payı (pt).
|
|
12
|
+
`unknown`'ın nedeni kapalı bir listeden gelir.
|
|
13
|
+
- **Doğrulama:** `fillTemplate`'in reddettiğini aynı `TemplateError` ile reddeder; hiçbir şey yazmaz.
|
|
14
|
+
Rapor değer taşımaz.
|
|
15
|
+
- **Çok satırlı değer** `capacity` ister. Bağlama manifesti onu `fit` bloğunda taşır:
|
|
16
|
+
`checkFit(b, d, {...m.options, ...m.fit})`.
|
|
17
|
+
- **Word'e karşı:** masaüstü 16'da ön kayıtlı kapıyla sınandı (FR4-WORD-FIT2). 210 satırın hepsi
|
|
18
|
+
`checkFit`'in dediği gibi dizildi: KR09'un bütün kutuları bandın iki yanında, ayrıca 14 kalibrasyon dalı.
|
|
19
|
+
- **Calibri genişlik tablosu** — `dist/fonts/calibri-metrics.js`.
|
|
20
|
+
- Carlito 1.104'ten (SIL OFL-1.1, ayrılmış ad "Carlito"); lisans metni yanında
|
|
21
|
+
(`dist/fonts/OFL-Carlito.txt`).
|
|
22
|
+
- Yalnız Calibri 6.23 ile eşit olduğu 344 kod noktası, dört kesim. Tabloda olmayan karakter `unknown`
|
|
23
|
+
(örneğin ₺).
|
|
24
|
+
|
|
25
|
+
### Değişenler
|
|
26
|
+
|
|
27
|
+
- Bağlama manifesti (repo içi, `templates/`) `fit: {capacity}` kazandı. `fillTemplate` ve `validateTemplate`
|
|
28
|
+
`capacity`'yi bilinmeyen seçenek saymayı sürdürür.
|
|
29
|
+
|
|
30
|
+
### Bilinen sınırlar
|
|
31
|
+
|
|
32
|
+
- **Yalnız Calibri** (tablo) ve yalnız sınanan kutu ve paragraf biçimleri ölçülür; geri kalanı `unknown`.
|
|
33
|
+
Başka Calibri yapıları (Mac, Word web) ve `compatibilityMode` 15 doğrulanmadı (ADR-0042 DOĞRULANMALI).
|
|
34
|
+
- **Çok satırlı değerde** taşan bir satırın kaç satır alacağını tarayıcı söyler (FR4b). Kapasitenin
|
|
35
|
+
sığabileceği durumda sonuç `unknown(WRAPS)`.
|
|
36
|
+
- **Word'de sınanmayan dallar `unknown`:** sondaki boşlukların belirlediği satır (`TRAILING_SPACE`, U+0020
|
|
37
|
+
dahil), iç boşluklu kutuda ya da sola dayalı olmayan satırda sekme (`TAB_INSET`, `TAB_ALIGNMENT`), şablonda
|
|
38
|
+
olmayan paragraf stili (`STYLE_MISSING`), `xml:space` korunmayan kenar boşluğu (`WHITESPACE_UNPRESERVED`).
|
|
39
|
+
KR09'un örneklerinde hiçbiri yok (0 `unknown`).
|
|
40
|
+
|
|
41
|
+
## 0.2.0-alpha — 2026-10-26 (yayınlandı)
|
|
42
|
+
|
|
43
|
+
### Eklenenler
|
|
44
|
+
|
|
45
|
+
- **Çok satırlı değer** ([ADR-0039](./docs/adr/0039-multi-line-values.md)) —
|
|
46
|
+
`fillTemplate(bytes, data, {expectedTags?, multiline?})` ve
|
|
47
|
+
`validateTemplate(bytes, {expectedTags, multiline?})`. `multiline`'ın adlandırdığı etikette LF bir
|
|
48
|
+
satır sonudur: satırlar etiketin kendi run'ında, aralarında `w:br`; run'ın biçimi her satırda.
|
|
49
|
+
Okuma-geri `w:t` + `w:br` dizisini karşılaştırır. Şablonda olmayan ad `UNKNOWN_MULTILINE_TAG`.
|
|
50
|
+
Word'de (masaüstü 16) KR09'un iki uzun kutusunda ölçüldü: Calibri 8,5 pt'de 3 ve 2 satır sığıyor,
|
|
51
|
+
fazlası kırpılıyor.
|
|
52
|
+
|
|
53
|
+
### Değişenler
|
|
54
|
+
|
|
55
|
+
- Satır sonu kuralı: tek satırlı etikette LF de, her etikette CR, CRLF, U+2028 ve U+2029 eskisi gibi
|
|
56
|
+
`VALUE_LINE_BREAK`. Motor değeri normalleştirmez.
|
|
57
|
+
|
|
58
|
+
### Bilinen sınırlar
|
|
59
|
+
|
|
60
|
+
- `importDocx` `w:br`'yi okumuyor: çok satırlı bir değer editörde tek satıra birleşir; düzenlenip
|
|
61
|
+
export edilirse satır sonları kaybolur (FR4).
|
|
62
|
+
- Kutuya sığmayan değer Word'de sessizce kırpılır; sığma denetimi bugün çağıranın işi (FR4).
|
|
63
|
+
|
|
64
|
+
Paketin dışında (repo içi, `files`'a girmez): şablon tarifleri, bağlama manifesti ve alan kaydı v0
|
|
65
|
+
(`templates/`, ADR-0040/0041) — PeriKont'un KR09 şablonu bunlarla üretilir. Şablonun kendisi
|
|
66
|
+
`templates/kr09/KR09-template.docx`'te commit'li.
|
|
67
|
+
|
|
68
|
+
## 0.1.0-alpha — 2026-10-17 (yayını sahip yapar)
|
|
69
|
+
|
|
70
|
+
İlk açık alfa. Editörün kendi yüzeyi (`.`, `./element`, `./react`) değişmedi ve 1.0
|
|
71
|
+
öncesi.
|
|
72
|
+
|
|
73
|
+
### Eklenenler
|
|
74
|
+
|
|
75
|
+
- **`/docx` alt yolu** — DOM'suz; Node'da ve Deno'da (ör. Supabase Edge Functions) sınandı,
|
|
76
|
+
tarayıcı için de yazıldı (Chrome 152'de yalnız incelendi). Hiçbir ağ isteği atmaz.
|
|
77
|
+
- `fillTemplate(bytes, data, {expectedTags?})` — bir `.docx` şablonunun `{etiket}`lerini
|
|
78
|
+
doldurur. `{bytes, documentXml, report}` döndürür.
|
|
79
|
+
- `inspectTemplate(bytes)` — şablondaki etiketler (kutunun `wp:docPr` kimliği ve sayfasıyla),
|
|
80
|
+
doldurmayı durduracak sorunlar ve uyarılar. Şablon sorununda atmaz.
|
|
81
|
+
- `validateTemplate(bytes, {expectedTags})` — bağlama listesini tam küme olarak denetler.
|
|
82
|
+
- `TemplateError` — `problems` dizisi; her sorunun `code`'u sözleşmedir.
|
|
83
|
+
- `ENGINE_VERSION`.
|
|
84
|
+
- `importDocx`, `exportDocx` — editörün kendi IO'su; şekilleri alfa boyunca kararsız.
|
|
85
|
+
|
|
86
|
+
### Doldurma kuralları (ADR-0037, ADR-0038)
|
|
87
|
+
|
|
88
|
+
- Etiket bir `w:t`'nin metninin tamamıdır: `{firma_adi}`, ad `[a-z][a-z0-9_]*`.
|
|
89
|
+
- Etiketler yalnız metin kutularında (`mc:AlternateContent`). Kutunun iki kopyası
|
|
90
|
+
(`mc:Choice` ve `mc:Fallback`) birlikte yazılır; önceden yapısal olarak eşit değillerse
|
|
91
|
+
reddedilir, sonra eşitlikleri yeniden denetlenir.
|
|
92
|
+
- Eksik anahtar doldurmayı durdurur; eksiklerin hepsi tek hatada raporlanır. `null`, `""` ve
|
|
93
|
+
yalnız boşluktan oluşan değer **boştur**: serbesttir, `report.empty`'de listelenir.
|
|
94
|
+
- Değer string olmalı. Satır sonu, sekme ve XML'in kabul etmediği karakterler reddedilir.
|
|
95
|
+
- Rapor, sorunlar ve hata mesajları hiçbir değeri taşımaz.
|
|
96
|
+
- Yalnız `word/document.xml` yeniden yazılır; başka her parçanın baytları aynen kopyalanır.
|
|
97
|
+
|
|
98
|
+
### Bilinen sınırlar
|
|
99
|
+
|
|
100
|
+
- Yalnız ana belge doldurulur. Üst/alt bilgi, dipnot, son not, yorum, grafik ya da
|
|
101
|
+
`docProps` metnindeki bir parantez hata verir.
|
|
102
|
+
- Döngü (`{#…}`), koşul, görsel (`{%…}`), bölünmüş etiket, gövde paragrafındaki etiket yok.
|
|
103
|
+
- Çok satırlı değer yok (satır sonu reddedilir); politika FR3'te.
|
|
104
|
+
- Sıkıştırılmış `.docx` baytları çalışma ortamına göre değişir; ortamlar arasında
|
|
105
|
+
karşılaştırmayı `documentXml`'in özetiyle yapın.
|
|
106
|
+
- Gereken platform API'leri: `TextEncoder`/`TextDecoder` ve
|
|
107
|
+
`CompressionStream`/`DecompressionStream("deflate-raw")` — Node 20.12+ ya da 21.2+, Deno,
|
|
108
|
+
güncel tarayıcılar. Sınanan: Node 24.13.1, Deno 2.1.4.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Samet Alemdaroğlu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,286 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @sametalmdr/word-editor
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Tarayıcıda çalışan bir **sayfa tuvali** editörü: sabit sayfa yüzeyleri
|
|
4
|
+
üzerinde mutlak konumlu metin kutularının içeriğini ve yerleşimini düzenler,
|
|
5
|
+
gerçek `.docx` dosyalarını açar ve orijinal paketi yamalayarak geri kaydeder.
|
|
6
|
+
Akan metin / sayfalama / tablo yok (ADR-0006). Sıfır runtime bağımlılık, saf
|
|
7
|
+
ESM, MIT lisanslı.
|
|
8
|
+
|
|
9
|
+
> ⚠️ **Durum (2026-10-26): 0.3.0-alpha hazır (0.2.0-alpha'ya `checkFit` eklendi); npm'de yayını sahip yapar. 0.2.0-alpha npm'de.** Editör çalışıyor:
|
|
10
|
+
> `.docx` aç, metin yaz, kutu taşı, kalın/italik/altı çizili, punto, hizalama,
|
|
11
|
+
> girinti, Kaydet. **Gerçek Word'de doğrulanan:** metin, kutu taşıma ve
|
|
12
|
+
> kalın — kaydedilen dosya onarımsız açılıyor ve değişiklik görünüyor.
|
|
13
|
+
> İtalik ve altı çizili aynı yazma yolundan geçiyor, ama Word'de ayrıca
|
|
14
|
+
> açılmadı. Punto, hizalama ve girinti dosyaya yazılıyor ama **Word'de henüz
|
|
15
|
+
> doğrulanmadı** (FIDELITY.md'de AÇIK). **Bugün yalnız örnek sayfalardan
|
|
16
|
+
> kullanılabiliyor** (aşağıda `app.html`): paketin public API'si `createEditor()`
|
|
17
|
+
> (bir `doc` alır, tuval editörünü dışa vermez). `.docx` import/export'u ve şablon doldurma
|
|
18
|
+
> **`/docx` alt yolunda** (aşağıda; `0.3.0-alpha`), `/canvas` FR4b'de geliyor
|
|
19
|
+
> ([docs/MASTER-PLAN.md](./docs/MASTER-PLAN.md)). Kaydedilmeyen düzenlemeler ve bilinen
|
|
20
|
+
> iki hata (yapıştırılan kutu kaydı engelliyor, silinen kutu sessizce
|
|
21
|
+
> kayboluyor): [FIDELITY.md](./FIDELITY.md) "Kutu yerleşimi" bölümü. Yol
|
|
22
|
+
> haritası: [ARCHITECTURE.md](./ARCHITECTURE.md) §6.
|
|
23
|
+
|
|
24
|
+
Bu proje Microsoft Word'ün bir klonu değildir ve Microsoft ile hiçbir
|
|
25
|
+
bağlantısı yoktur.
|
|
26
|
+
|
|
27
|
+
## Kurulum
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install @sametalmdr/word-editor@0.3.0-alpha
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Saf HTML ile kullanım
|
|
34
|
+
|
|
35
|
+
Build adımı gerekmez.
|
|
36
|
+
|
|
37
|
+
```html
|
|
38
|
+
<link rel="stylesheet" href="./node_modules/@sametalmdr/word-editor/dist/styles.css" />
|
|
39
|
+
<word-editor></word-editor>
|
|
40
|
+
<script type="module">
|
|
41
|
+
import "@sametalmdr/word-editor/element";
|
|
42
|
+
</script>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## React ile kullanım
|
|
46
|
+
|
|
47
|
+
`react` bir optional peer dependency'dir — kendi React sürümünüzü kurmanız
|
|
48
|
+
gerekir.
|
|
49
|
+
|
|
50
|
+
```jsx
|
|
51
|
+
import { WordEditor } from "@sametalmdr/word-editor/react";
|
|
52
|
+
import "@sametalmdr/word-editor/styles.css";
|
|
53
|
+
|
|
54
|
+
function App() {
|
|
55
|
+
return <WordEditor />;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Framework-agnostic çekirdek API
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
import { createEditor } from "@sametalmdr/word-editor";
|
|
63
|
+
|
|
64
|
+
const editor = createEditor({ container: document.getElementById("root") });
|
|
65
|
+
// ...
|
|
66
|
+
editor.destroy();
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## `/docx` — şablon doldurma (DOM'suz; Node, Deno ve tarayıcı için yazıldı)
|
|
70
|
+
|
|
71
|
+
`{etiket}`li bir `.docx` şablonunu veriyle doldurur. Orijinal paketi yamalar: yalnız
|
|
72
|
+
`word/document.xml` yeniden yazılır, başka her parça bayt bayt aynı kalır. Hiçbir ağ isteği
|
|
73
|
+
atmaz; sunucuda (ör. Supabase Edge Functions) ve tarayıcıda aynı fonksiyon. Kapılarla sınanan:
|
|
74
|
+
Node 24.13.1 ve Deno 2.1.4; tarayıcıda (Chrome 152) yalnız incelendi, kanıt sınıfıyla değil.
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
import { fillTemplate, inspectTemplate, TemplateError } from "@sametalmdr/word-editor/docx";
|
|
78
|
+
|
|
79
|
+
// template: bir .docx dosyasının baytları (Uint8Array)
|
|
80
|
+
try {
|
|
81
|
+
const { bytes, documentXml, report } = await fillTemplate(template, {
|
|
82
|
+
firma_adi: "Alrosoft Ltd",
|
|
83
|
+
rapor_no: "RPR-2026-0001",
|
|
84
|
+
notlar: null, // boş: serbest, report.empty'de listelenir
|
|
85
|
+
});
|
|
86
|
+
// bytes: doldurulmuş .docx
|
|
87
|
+
// documentXml: doldurulmuş word/document.xml, sıkıştırılmamış — çalışma ortamları
|
|
88
|
+
// arasında karşılaştırmayı bunun özetiyle yapın (zip baytları ortama göre değişir)
|
|
89
|
+
// report: etiket -> [{docPrId, page}], empty, unused, warnings, counts, engine
|
|
90
|
+
} catch (err) {
|
|
91
|
+
if (!(err instanceof TemplateError)) throw err;
|
|
92
|
+
for (const p of err.problems) console.log(p.code, p.tag, p.page); // hepsi birlikte
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const info = await inspectTemplate(template); // doldurmadan: etiketler, sorunlar, uyarılar
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Kurallar ([ADR-0037](./docs/adr/0037-template-fill-engine.md),
|
|
99
|
+
[ADR-0038](./docs/adr/0038-generated-output-keeps-both-copies-equal.md)):
|
|
100
|
+
|
|
101
|
+
- Etiket bir `w:t`'nin metninin tamamıdır: `{firma_adi}`, ad `[a-z][a-z0-9_]*`. Bölünmüş
|
|
102
|
+
etiket, `{ ad }`, `{#döngü}`, `{%görsel}` ve "Tarih: {tarih}" gibi karışık metin reddedilir.
|
|
103
|
+
- Etiket yalnız metin kutusunda olabilir. Kutunun iki kopyası (`mc:Choice` ve `mc:Fallback`)
|
|
104
|
+
birlikte yazılır ve eşit kaldıkları denetlenir — Word yalnız Choice'u okur, yanlış bir
|
|
105
|
+
Fallback Word'de görünmez (FILL-E2).
|
|
106
|
+
- Eksik anahtar hata; eksiklerin hepsi tek `TemplateError`'da. `null`, `""` ve yalnız boşluk
|
|
107
|
+
boştur: serbest, raporlanır.
|
|
108
|
+
- Değer string olmalı; sekme ve denetim karakterleri reddedilir. Tarih ve sayı biçimlemek
|
|
109
|
+
çağıranın işi.
|
|
110
|
+
- Satır sonu yalnız `multiline` seçeneğinin adlandırdığı etikette ve yalnız LF olarak
|
|
111
|
+
([ADR-0039](./docs/adr/0039-multi-line-values.md)): her satır etiketin kendi run'ında, aralarında
|
|
112
|
+
`w:br`, run'ın biçimi her satırda. CR, CRLF, U+2028 ve U+2029 her etikette reddedilir — motor
|
|
113
|
+
değeri sessizce değiştirmez, normalleştirmek çağıranın işi. Şablonda olmayan bir ad
|
|
114
|
+
`UNKNOWN_MULTILINE_TAG`:
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
await fillTemplate(template, { ...data, notlar: "Birinci satır\nİkinci satır" }, { multiline: ["notlar"] });
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Kutunun alabileceğinden fazla satır Word'de sessizce kırpılır (FR3-WORD-ML2); `checkFit` bunu
|
|
121
|
+
doldurmadan önce söyler (aşağıda).
|
|
122
|
+
- `validateTemplate(bytes, {expectedTags, multiline})` şablonun etiketlerini bir listeyle tam küme
|
|
123
|
+
olarak karşılaştırır. Bilinmeyen seçenek (`{linebreaks: true}` gibi) hata verir.
|
|
124
|
+
- Rapor, sorunlar ve hata mesajları hiçbir değeri taşımaz.
|
|
125
|
+
|
|
126
|
+
### `checkFit` — değer kutusuna sığıyor mu? ([ADR-0042](./docs/adr/0042-dom-free-fit-check.md))
|
|
127
|
+
|
|
128
|
+
Word kutuya sığmayan değeri sessizce kırpar. `checkFit` doldurmadan önce her değerin satırını şablonun
|
|
129
|
+
kendi kutusuyla karşılaştırır. Tarayıcı gerekmez: Calibri'nin genişlikleri, onunla metrik-uyumlu
|
|
130
|
+
Carlito'dan (OFL-1.1) bir tablo olarak paketin içinde.
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
import { checkFit, fillTemplate } from "@sametalmdr/word-editor/docx";
|
|
134
|
+
|
|
135
|
+
const fit = await checkFit(template, data, { ...manifest.options, ...manifest.fit });
|
|
136
|
+
if (!fit.ok) {
|
|
137
|
+
for (const t of fit.tags) {
|
|
138
|
+
for (const o of t.occurrences) {
|
|
139
|
+
if (o.status === "overflows" || o.status === "unknown") console.log(t.name, o.status, o.reason, o.marginPt);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
- **Durumlar:** her occurrence `fits`, `overflows`, `unknown` ya da `empty` döner.
|
|
146
|
+
- Ölçülen occurrence en dar satırının `widthPt`, `availablePt` ve `marginPt` değerlerini taşır.
|
|
147
|
+
- `unknown` (ve sekmesini durağından iten `overflows`) kapalı bir listeden bir `reason` taşır.
|
|
148
|
+
- Etiketin durumu, occurrence'larının en kötüsüdür.
|
|
149
|
+
- **Tolerans:** τ = 0,05 pt + glif başına 0,025 pt.
|
|
150
|
+
- `fits`: satır τ payıyla sığar.
|
|
151
|
+
- `overflows`: satır τ'nun ötesinde taşar.
|
|
152
|
+
- Aradaki `unknown(BORDERLINE)` için karar verilmez.
|
|
153
|
+
- **Sondaki boşluklar:** Word'ün onları kenarın ötesine asılı bırakıp bırakmadığı sınanmadı. `fits` onları
|
|
154
|
+
sayarak sığmayı, `overflows` onlarsız taşmayı ister; yalnız onlar karar veriyorsa `unknown(TRAILING_SPACE)`.
|
|
155
|
+
Değeri kırpmak bu durumu ortadan kaldırır.
|
|
156
|
+
- **Çok satırlı değer** `capacity` ister: `{etiket: satır}`, manifestin `fit` bloğunda. Taşan satır en az
|
|
157
|
+
bir satır daha alır. Satır sayısı ile taşan satır sayısının toplamı kapasiteyi geçerse `overflows`.
|
|
158
|
+
- **Kırma yok:** satır kırma noktası seçilmez. Ölçülemeyen biçim `unknown` döner (başka bir font,
|
|
159
|
+
döndürülmüş ya da gruplanmış kutu, `kern`, sola dayalı olmayan sekme durağı, iç boşluklu kutuda ya da
|
|
160
|
+
sola dayalı olmayan satırda sekme vb.).
|
|
161
|
+
- **Doğrulama:** `fillTemplate`'in reddettiğini aynı `TemplateError` ile reddeder. Hiçbir şey yazmaz;
|
|
162
|
+
rapor değer taşımaz.
|
|
163
|
+
- **Öneri:** onayı `overflows` **ve** `unknown` durumunda kapatın.
|
|
164
|
+
|
|
165
|
+
Bilinen sınırlar ve sınanan ortamlar: [CHANGELOG.md](./CHANGELOG.md).
|
|
166
|
+
|
|
167
|
+
## Ürün sayfası — `app.html` (DOCX aç → düzenle → kaydet)
|
|
168
|
+
|
|
169
|
+
Ribbon'lı tam editör. Paket henüz bu yüzeyi dışa vermediği için (yukarıdaki
|
|
170
|
+
durum notu) bugün yalnız repo içinden çalışır:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
npm run serve
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
http://127.0.0.1:8080/examples/static/app.html
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Dosya** sekmesindeki **Dosya Seç** ile `test/corpus/` altındaki bir belgeyi
|
|
181
|
+
seç (dosya yalnız okunur, değiştirilmez). Çift tık bir kutunun içinde metin moduna geçer,
|
|
182
|
+
tek tık kutuyu seçer (ADR-0024). **Kaydet (.docx)** orijinal paketi yamalayarak
|
|
183
|
+
indirir. "PDF indir" henüz bağlı değil — bugün PDF için görüntüleyicinin
|
|
184
|
+
Ctrl+P'si var (aşağıda).
|
|
185
|
+
|
|
186
|
+
## Corpus görüntüleyici (demo)
|
|
187
|
+
|
|
188
|
+
46 corpus belgesini gerçek renderer ile tarayıcıda gösterir.
|
|
189
|
+
**Görüntüleyici — düzenleme yok.** İki komut:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
npm run corpus:canvas
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
npm run serve
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Sonra tarayıcıda aç:
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
http://127.0.0.1:8080/examples/static/viewer.html
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Solda 46 belge, seçince sayfaları çizilir; başlıkta kutu/dekorasyon/sayfa
|
|
206
|
+
sayısı ve render süresi görünür.
|
|
207
|
+
|
|
208
|
+
**Çift tıklayarak açılmaz, ve bu ölçülmüş bir kısıt.** Chrome 151 /
|
|
209
|
+
Windows 10 22H2'de `file://` üzerinde statik ES modül import'u, dinamik
|
|
210
|
+
`import()` ve `fetch()` **üçü de bloklanıyor**; yalnızca inline klasik
|
|
211
|
+
`<script>` koşuyor. Gerçek renderer'ı import etmenin başka yolu yok. Dört
|
|
212
|
+
ölçümün tamamı [docs/viewer-measurement.md](./docs/viewer-measurement.md)
|
|
213
|
+
§0'da; sunucu `node:http` ile yazıldı, **sıfır bağımlılık**, yalnızca
|
|
214
|
+
loopback. Aynı kısıt `examples/static/canvas.html` ve `index.html` için de
|
|
215
|
+
geçerli.
|
|
216
|
+
|
|
217
|
+
`npm run corpus:canvas` Python ister (`scripts/docx-to-canvas-json.py`
|
|
218
|
+
dönüştürücüsünü çağırır) ve bu yüzden `npm run ci`'nin parçası **değildir** —
|
|
219
|
+
`corpus:check` ve `corpus:names` ile aynı gerekçe. Çıktı
|
|
220
|
+
`examples/static/corpus-json/` altına yazılır, gitignore'ludur, her koşumda
|
|
221
|
+
baştan üretilir. `test/corpus/` **okunur, asla yazılmaz** (CLAUDE.md #16).
|
|
222
|
+
|
|
223
|
+
### PDF — Tier 0
|
|
224
|
+
|
|
225
|
+
Görüntüleyicide **Ctrl+P → "PDF olarak kaydet"**. Sayfa yüzeyleri belgenin
|
|
226
|
+
kendi boyutunda basılır (A4 dikey, A4 yatay ve A5 corpus'ta hepsi var), UI
|
|
227
|
+
kromu gizlenir.
|
|
228
|
+
|
|
229
|
+
**Bu bizim PDF writer'ımız değil, tarayıcınınki** — `ARCHITECTURE.md` §7'nin
|
|
230
|
+
Tier 0'ı. Sunucuda üretilen, gömülü fontlu PDF FR5'te geliyor (eski MP10, yol
|
|
231
|
+
haritasındaki P7); yolunu — kendi yazıcımız, pdf-lib ya da Cloudflare Browser Run — FR5
|
|
232
|
+
başında sahip seçiyor (ADR-0036 Karar 5).
|
|
233
|
+
|
|
234
|
+
**Gözle kontrol — henüz yapılmadı, yapılacaksa şöyle:** üç belgeyi seçip
|
|
235
|
+
Ctrl+P ile önizlemeye bak; kâğıt boyutu belgenin kendi boyutuna oturmalı,
|
|
236
|
+
kenar boşluğu olmamalı, sol liste ve üst başlık görünmemeli.
|
|
237
|
+
|
|
238
|
+
| Belge | Beklenen kâğıt | Neden bu üçü |
|
|
239
|
+
|---|---|---|
|
|
240
|
+
| `AA01` | A4 dikey (595.5×842 pt) | corpus'un çoğunluğu |
|
|
241
|
+
| `PK01` | **A4 YATAY** (842×595.5 pt) | sabit `A4` varsayımının kırılacağı yer |
|
|
242
|
+
| `R001` | **A5** (420×595.5 pt) | ikinci kırılma noktası; 71 sayfa |
|
|
243
|
+
|
|
244
|
+
Üçü de doğru basıyorsa sayfa boyutu belge başına yazılıyor demektir.
|
|
245
|
+
|
|
246
|
+
Ölçüm sonuçları: [docs/viewer-measurement.md](./docs/viewer-measurement.md).
|
|
247
|
+
|
|
248
|
+
## Tuval — kutu düzenleme (demo, P3b-a)
|
|
249
|
+
|
|
250
|
+
Görüntüleyiciden farklı olarak **burada düzenleme var** — metin değil, kutu
|
|
251
|
+
geometrisi: seç, tutamakla sürükle/boyutlandır, Ctrl+Z ile geri al,
|
|
252
|
+
kopyala/yapıştır, dekoratif bir şeklin kenarına yaklaştırıp snap'i gör.
|
|
253
|
+
`src/canvas/`'ın dokuz saf modülü + `CanvasController` + `Overlay`, gerçek
|
|
254
|
+
bir tarayıcıya bağlı (`docs/adr/0018-canvas-interaction-layer.md`).
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
npm run serve
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
http://127.0.0.1:8080/examples/static/canvas.html
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Dosya seçiciyle bir belge JSON'u yükle: `test/fixtures/canvas/fifty-boxes.json`
|
|
265
|
+
(50 kutu, 5 dekorasyon, 2 sayfa) hazır bir örnek; `npm run corpus:canvas`'ın
|
|
266
|
+
ürettiği `examples/static/corpus-json/*.json` de aynı formatta çalışır.
|
|
267
|
+
|
|
268
|
+
**Ölçülmemiş sabitler, sayfanın kendi geçici değerleri — kütüphaneye değil:**
|
|
269
|
+
tutamak boyutu, snap eşiği, kademe eşikleri hiçbiri ölçülmedi (Ö2/Ö4,
|
|
270
|
+
ADR-0018 §9.0). `canvas.html` kendi `EXAMPLE_METRICS` nesnesini enjekte
|
|
271
|
+
ediyor; `src/canvas/controller.js`'in `requireMetrics`'i eksik alanda hâlâ
|
|
272
|
+
gerçek `TypeError` atıyor, `src/` altına hiçbir varsayılan sızmadı.
|
|
273
|
+
|
|
274
|
+
Aynı `file://` kısıtı geçerli (yukarıdaki görüntüleyici bölümüne bakınız).
|
|
275
|
+
~~Metin düzenleme bu turun kapsamında değil~~ — 2026-08-29'dan beri
|
|
276
|
+
(ADR-0024) çift tık kutunun içinde metin moduna geçiyor, ve sayfa artık
|
|
277
|
+
`.docx` da açıp kaydedebiliyor. Ürün yüzeyi ise `app.html` (yukarıda).
|
|
278
|
+
|
|
279
|
+
## Mimari
|
|
280
|
+
|
|
281
|
+
Tasarım kararları için [ARCHITECTURE.md](./ARCHITECTURE.md),
|
|
282
|
+
uyumluluk sözleşmesi için [FIDELITY.md](./FIDELITY.md).
|
|
283
|
+
|
|
284
|
+
## Lisans
|
|
285
|
+
|
|
286
|
+
MIT — bkz. [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The clipboard payload for a set of boxes — `null` if the selection is
|
|
3
|
+
* empty or any id no longer names a real box (a stale selection copying
|
|
4
|
+
* nothing meaningful is a no-op, not a partial copy).
|
|
5
|
+
*
|
|
6
|
+
* @param {import("../model/node.js").Doc} doc
|
|
7
|
+
* @param {import("../model/node.js").NodeId[]} containerIds
|
|
8
|
+
* @returns {BoxPayload | null}
|
|
9
|
+
*/
|
|
10
|
+
export function serializeBoxes(doc: import("../model/node.js").Doc, containerIds: import("../model/node.js").NodeId[]): BoxPayload | null;
|
|
11
|
+
/**
|
|
12
|
+
* The plain-text mirror written to the system clipboard's `text/plain`
|
|
13
|
+
* slot alongside the real payload (§7.1) — every paragraph of every box,
|
|
14
|
+
* in payload order, joined the same way `serializeToText` joins a text
|
|
15
|
+
* selection's paragraphs.
|
|
16
|
+
* @param {BoxPayload} payload
|
|
17
|
+
* @returns {string}
|
|
18
|
+
*/
|
|
19
|
+
export function payloadToText(payload: BoxPayload): string;
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {object} MintedBoxIds
|
|
22
|
+
* @property {import("../model/node.js").NodeId} containerId
|
|
23
|
+
* @property {import("../model/node.js").NodeId[]} paragraphIds same length and order as `box.paragraphs`
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Fresh ids for one payload box, minted from `ids` — NEVER the ids the
|
|
27
|
+
* payload itself carries (those are the ORIGINAL box's, and reusing them
|
|
28
|
+
* would collide the moment the original still exists, CANV12's own
|
|
29
|
+
* target). Minted before any step exists (ADR-0003: `apply()` never mints
|
|
30
|
+
* an id) — the same ordering `commands/clipboard.js`'s `pasteText` already
|
|
31
|
+
* uses for a pasted paragraph's id, generalized to a whole box.
|
|
32
|
+
*
|
|
33
|
+
* @param {BoxPayloadEntry} box
|
|
34
|
+
* @param {import("../model/ids.js").IdFactory} ids
|
|
35
|
+
* @returns {MintedBoxIds}
|
|
36
|
+
*/
|
|
37
|
+
export function mintBoxIds(box: BoxPayloadEntry, ids: import("../model/ids.js").IdFactory): MintedBoxIds;
|
|
38
|
+
/**
|
|
39
|
+
* @typedef {object} PastePage
|
|
40
|
+
* @property {number} page 1-based, the ACTIVE page paste targets — never the page the boxes were copied from (§7.2)
|
|
41
|
+
* @property {number} width
|
|
42
|
+
* @property {number} height
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* @typedef {object} PastedBox
|
|
46
|
+
* @property {import("../model/node.js").Container} container fresh ids throughout
|
|
47
|
+
* @property {import("../model/node.js").BoxLayout} layout
|
|
48
|
+
*/
|
|
49
|
+
/**
|
|
50
|
+
* Rebuilds `payload` as fresh containers + layouts, ready for the (future)
|
|
51
|
+
* caller to turn into `insertContainerStep`s — one transaction, so the
|
|
52
|
+
* whole paste is one undo entry.
|
|
53
|
+
*
|
|
54
|
+
* Relative geometry is preserved EXACTLY (§7.4): the offset from
|
|
55
|
+
* `payload.origin` to its post-paste position is computed ONCE, from the
|
|
56
|
+
* group's own bounding rect, and applied IDENTICALLY to every box's own
|
|
57
|
+
* absolute `{x,y}` — never computed per box. A per-box offset (e.g. each
|
|
58
|
+
* box separately clamped against the page) would let two boxes drift
|
|
59
|
+
* apart or together depending on which one needed clamping (CANV9's own
|
|
60
|
+
* target): two boxes 40pt apart must land 40pt apart, whether or not the
|
|
61
|
+
* paste needed to shift for the page edge.
|
|
62
|
+
*
|
|
63
|
+
* Falling outside the target page CLIPS the whole group's bounding rect
|
|
64
|
+
* into it (§7.2) — smart placement is not attempted; ARCHITECTURE.md:357
|
|
65
|
+
* already calls "no overlap" an unrealistic goal, and clipping the whole
|
|
66
|
+
* group keeps that same "don't pretend to solve overlap" stance instead
|
|
67
|
+
* of inventing a different unsolved problem (per-box collision avoidance).
|
|
68
|
+
*
|
|
69
|
+
* @param {BoxPayload} payload
|
|
70
|
+
* @param {import("../model/ids.js").IdFactory} ids
|
|
71
|
+
* @param {PastePage} targetPage
|
|
72
|
+
* @param {number} pasteOffsetPt pt — injected, no default (an unmeasured UI constant, CanvasMetrics' `pasteOffsetPt`)
|
|
73
|
+
* @returns {PastedBox[]}
|
|
74
|
+
*/
|
|
75
|
+
export function pasteBoxes(payload: BoxPayload, ids: import("../model/ids.js").IdFactory, targetPage: PastePage, pasteOffsetPt: number): PastedBox[];
|
|
76
|
+
/** Bumped when the shape changes incompatibly — mirrors document-json.js's own field. */
|
|
77
|
+
export const BOX_PAYLOAD_VERSION: 1;
|
|
78
|
+
export type BoxPayloadParagraph = {
|
|
79
|
+
id: import("../model/node.js").NodeId;
|
|
80
|
+
pPrRef?: string | undefined;
|
|
81
|
+
runs: {
|
|
82
|
+
text: string;
|
|
83
|
+
marks: import("../model/node.js").Marks;
|
|
84
|
+
}[];
|
|
85
|
+
};
|
|
86
|
+
export type BoxPayloadEntry = {
|
|
87
|
+
/**
|
|
88
|
+
* a fresh, field-by-field copy — never a live reference
|
|
89
|
+
*/
|
|
90
|
+
layout: Partial<import("../model/node.js").BoxLayout>;
|
|
91
|
+
paragraphs: BoxPayloadParagraph[];
|
|
92
|
+
};
|
|
93
|
+
export type BoxPayload = {
|
|
94
|
+
version: number;
|
|
95
|
+
/**
|
|
96
|
+
* the copied selection's own bounding-rect top-left (ADR-0018 §7.3's "grubun sol-üstü")
|
|
97
|
+
*/
|
|
98
|
+
origin: {
|
|
99
|
+
x: number;
|
|
100
|
+
y: number;
|
|
101
|
+
};
|
|
102
|
+
boxes: BoxPayloadEntry[];
|
|
103
|
+
};
|
|
104
|
+
export type MintedBoxIds = {
|
|
105
|
+
containerId: import("../model/node.js").NodeId;
|
|
106
|
+
/**
|
|
107
|
+
* same length and order as `box.paragraphs`
|
|
108
|
+
*/
|
|
109
|
+
paragraphIds: import("../model/node.js").NodeId[];
|
|
110
|
+
};
|
|
111
|
+
export type PastePage = {
|
|
112
|
+
/**
|
|
113
|
+
* 1-based, the ACTIVE page paste targets — never the page the boxes were copied from (§7.2)
|
|
114
|
+
*/
|
|
115
|
+
page: number;
|
|
116
|
+
width: number;
|
|
117
|
+
height: number;
|
|
118
|
+
};
|
|
119
|
+
export type PastedBox = {
|
|
120
|
+
/**
|
|
121
|
+
* fresh ids throughout
|
|
122
|
+
*/
|
|
123
|
+
container: import("../model/node.js").Container;
|
|
124
|
+
layout: import("../model/node.js").BoxLayout;
|
|
125
|
+
};
|