fix: A27 phase 2a — éditeur 2 516 L extrait via page-data JSON (v7.22.0)
- `_page_editor_scripts.html` : le gros bloc interpolé (2 516 L) part vers
`static/js/page_editor_scripts.js` — recette « config JSON » : les 8
interpolations Jinja lisent `PD = JSON.parse(#page-data)`, bloc JSON qui
EXISTAIT DÉJÀ juste avant le script (même ordre d'exécution), garde
`__fdEditorScriptsLoaded` préservée, node --check vert.
- Route `view_page_root` : page_data enrichi de updated_at, created_at,
user_id, is_shared (dérivé HOISTÉ : une seule expression sert le ctx ET le
JSON) et clip_icon (macro fd_icon rendue côté serveur). workspace_key reste
vide comme avant (jamais défini dans ce ctx → parité stricte).
8 tests adaptés à l'extraction (ils lisaient le template SOURCE) :
- test_ai_writing ×2 (+ helper _read_js), test_pwa_offline,
test_v511 front_end_wired, test_v55 ×3 → lisent le JS extrait
- test_page_editor_renders_page_is_shared → parsing du JSON #page-data
(`is_shared is True`) — la valeur sert toujours à la page
Cumul A27 : 6 759 L extraites (13 904 → 7 145 inline). Reste : local_workspace
2 031, base 1 523 (structurel {% for %}/{% block %}), database_table 1 323,
settings 1 093, realtime 531, board 146 ≈ 6 653 L + 120 warnings eslint.
suite **1089/1089** · ruff OK · docs à jour
This commit is contained in:
@@ -270,8 +270,15 @@ def _read_template(name: str) -> str:
|
||||
return fh.read()
|
||||
|
||||
|
||||
def _read_js(name: str) -> str:
|
||||
"""A27 : le JS de l'éditeur vit dans static/js depuis l'extraction."""
|
||||
base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
with open(os.path.join(base, "static", "js", name), encoding="utf-8") as fh:
|
||||
return fh.read()
|
||||
|
||||
|
||||
def test_editor_has_ai_slash_commands(client):
|
||||
src = _read_template("_page_editor_scripts.html")
|
||||
src = _read_js("page_editor_scripts.js")
|
||||
for cmd in ("ai_write", "ai_summarize", "ai_translate", "ai_continue"):
|
||||
assert cmd in src
|
||||
assert "AI writing" in src
|
||||
@@ -280,7 +287,7 @@ def test_editor_has_ai_slash_commands(client):
|
||||
|
||||
|
||||
def test_editor_has_autocomplete(client):
|
||||
src = _read_template("_page_editor_scripts.html")
|
||||
src = _read_js("page_editor_scripts.js")
|
||||
assert "AIAC" in src
|
||||
assert "autocomplete" in src
|
||||
assert "AIAC.schedule" in src
|
||||
|
||||
@@ -98,7 +98,7 @@ def test_workspace_offline_banner_shows_pending(client):
|
||||
|
||||
|
||||
def test_editor_save_has_offline_hook():
|
||||
src = (ROOT / "app" / "templates" / "_page_editor_scripts.html").read_text(encoding="utf-8")
|
||||
src = (ROOT / "static" / "js" / "page_editor_scripts.js").read_text(encoding="utf-8")
|
||||
assert "FlowOffline" in src
|
||||
assert "savePageOffline" in src
|
||||
assert "navigator.onLine" in src
|
||||
|
||||
@@ -295,7 +295,14 @@ def test_page_editor_renders_page_is_shared(client):
|
||||
|
||||
r = client.get(f"/pages/{a}")
|
||||
assert r.status_code == 200
|
||||
assert "pageIsShared:true" in r.text
|
||||
# A27 : la valeur n'est plus interpolée dans le JS inline mais exposée
|
||||
# dans le JSON #page-data (le JS lit PD.is_shared)
|
||||
import json as _json
|
||||
import re as _re
|
||||
|
||||
m = _re.search(r'id="page-data"[^>]*>(.*?)</script>', r.text, _re.S)
|
||||
assert m, "bloc #page-data absent de la page"
|
||||
assert _json.loads(m.group(1))["is_shared"] is True
|
||||
|
||||
|
||||
def test_tree_is_shared_includes_link_shared_pages(client):
|
||||
|
||||
@@ -391,7 +391,7 @@ def test_block_templates_service_shapes():
|
||||
|
||||
def test_editor_front_end_wired(client):
|
||||
import pathlib
|
||||
src = pathlib.Path("app/templates/_page_editor_scripts.html").read_text(encoding="utf-8")
|
||||
src = pathlib.Path("static/js/page_editor_scripts.js").read_text(encoding="utf-8")
|
||||
base = pathlib.Path("app/templates/base.html").read_text(encoding="utf-8")
|
||||
assert "gtTok" in src and "fd-wiki-chip" in src # chip render + reader
|
||||
assert "wiki/pages" in src and "wiki/titles" in src # picker + label resolution
|
||||
|
||||
+3
-3
@@ -316,7 +316,7 @@ class TestBookmarkPersistence:
|
||||
|
||||
class TestLightbox:
|
||||
def test_editor_lightbox_supports_keyboard_navigation(self):
|
||||
tpl = Path("app/templates/_page_editor_scripts.html").read_text(encoding="utf-8")
|
||||
tpl = Path("static/js/page_editor_scripts.js").read_text(encoding="utf-8")
|
||||
assert "_openLightbox" in tpl
|
||||
assert "fd-lightbox-nav" in tpl
|
||||
assert "ArrowRight" in tpl and "ArrowLeft" in tpl
|
||||
@@ -343,7 +343,7 @@ class TestLightbox:
|
||||
|
||||
class TestInlinePreviews:
|
||||
def test_editor_renders_video_audio_pdf(self):
|
||||
tpl = Path("app/templates/_page_editor_scripts.html").read_text(encoding="utf-8")
|
||||
tpl = Path("static/js/page_editor_scripts.js").read_text(encoding="utf-8")
|
||||
assert "<video controls" in tpl
|
||||
assert "<audio controls" in tpl
|
||||
assert "embed_type==='pdf'" in tpl
|
||||
@@ -542,7 +542,7 @@ class TestCoverIcon:
|
||||
|
||||
class TestEditorEndpointPaths:
|
||||
def test_editor_uses_board_prefixed_endpoints(self):
|
||||
tpl = Path("app/templates/_page_editor_scripts.html").read_text(encoding="utf-8")
|
||||
tpl = Path("static/js/page_editor_scripts.js").read_text(encoding="utf-8")
|
||||
for endpoint in (
|
||||
"/board/api/pages/'+this.pid+'/cover",
|
||||
"/board/api/pages/'+this.pid+'/icon",
|
||||
|
||||
Reference in New Issue
Block a user