Add IMAP webmail tag, admin/opensource subpage tiers, store/cart, htmleditor, uploads
New __imap*/__smtpsend/__eval Jet tags give templates real IMAP (list/message/flag/delete/move/search/folders/accounts) and SMTP-send capability, backing the new /email webmail client (email.jet/ email.menu, assets/images/email.js + newemail.js) and its mainpagetemplate.jet-based page shell. Most of this tag family's source was already being built into the live site (Tag.cpp already registered __imap/__imaplist/__imapmessage/__imapflag/__imapdelete/ __eval) but had never actually been committed; this also registers and commits the remaining five (__imapmove/__imapfolders/ __imapsearch/__smtpsend/__imapaccounts). admin.page/admin.menu gain a real subpage tier (admin-email, admin-newemail, admin-invoices, admin-products, admin-users) replacing several previously top-level pages, mirrored by a similar opensource.page subpage tier (opensource-overview/asm1802/barantmail/ jet/serverframework/synthmax) - old top-level pages retired via git rename (asm1802.page, jet.page, serverframework.page, admin_invoices.page); barantmail.page is dropped outright, folded into opensource-barantmail.subpage. New storefront (store.page, store-createstore.subpage, barantstore.page) and cart flow (cart.jet, updatecartqty.proc, removecartitem.proc, editproduct.page/selectproduct.proc/ update_product.proc for inventory maintenance against the barant database). New document upload/download manager (documents.jet, documents_api.jet, documents_upload.proc, documents_delete.proc, assets/images/documents.js + documents-page.js) with a persistent floating panel, and a rich-text page editor (htmleditor.jet/.page, createhtmleditor.proc, savehtmleditor.proc, assets/images/htmleditor.js + its icon/logo assets). SESSIONCTL.tag: login now redirects back to the originally-requested page instead of always landing on /account ($[start:0] vs $[start] variable-name mismatch). main.css/menu.bar/invoices.menu/jet_overview.section/login.menu: styling and navigation updates for the above; new site assets (fonts, images, audio) referenced by them. jetc/build-assets.sh, list_jet_files.sh, lowercase_jet.py, strip_fragments.py: small dev tooling used while building the above.
This commit is contained in:
1 parent
b0cadc3f08
commit
c1491b044b
115 files changed
+6174
-137
No files matched your search
Executable
+96
@@ -0,0 +1,96 @@
|
||||
"""
|
||||
Strips the dead SPA-fragment dual-render wrapper from a barant-site/jet/*.jet
|
||||
route file, leaving just the real page content (the former "_full_NAME" tag
|
||||
body), unwrapped, with no fragment-flag try/catch, no _frag_NAME tag
|
||||
definition, no dispatch <if>, and no dead client-side SPA navigation script.
|
||||
|
||||
Structure being removed (present in all 20 files, verified consistent):
|
||||
|
||||
#api GET /NAME
|
||||
<try name="_fragerr">...<catch>...</try><tag name="_frag_NAME">
|
||||
... fragment-only content, NEVER actually invoked any more since the
|
||||
client-side SPA click handlers were already disabled earlier this
|
||||
session ...
|
||||
</tag><tag name="_full_NAME">
|
||||
... the REAL page content - full doctype/head/style/body wrapper ...
|
||||
<script>
|
||||
(function() {
|
||||
var FRAGMENT_EXCLUDED = [...];
|
||||
function pageNameFromPath(...) {...}
|
||||
function loadPage(...) {...}
|
||||
// SPA click/popstate interception disabled for now ...
|
||||
})();
|
||||
</script></body></html>
|
||||
</tag><if value1="$[fragflag]" value2="1" type="eq"><_frag_NAME /><else><_full_NAME /></if>
|
||||
|
||||
Kept: "#api GET /NAME\n" plus everything between "<tag name=\"_full_NAME\">"
|
||||
and its own matching close, MINUS the dead <script> block.
|
||||
"""
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def strip_dead_spa_script(content):
|
||||
pattern = re.compile(
|
||||
r"<script>\s*\(function\(\)\s*\{.*?SPA click/popstate interception disabled.*?\}\)\(\);\s*</script>",
|
||||
re.DOTALL,
|
||||
)
|
||||
new_content, n = pattern.subn("", content, count=1)
|
||||
return new_content, n
|
||||
|
||||
|
||||
def strip_fragment_wrapper(content, page_name):
|
||||
lines = content.split("\n", 1)
|
||||
assert lines[0].startswith("#api GET /"), f"unexpected first line: {lines[0]!r}"
|
||||
api_line = lines[0]
|
||||
rest = lines[1] if len(lines) > 1 else ""
|
||||
|
||||
start_marker = (
|
||||
'<try name="_fragerr"><set name="fragflag" expr="$[fragment]" />'
|
||||
'<catch><set name="fragflag" value="" /></try>'
|
||||
f'<tag name="_frag_{page_name}">'
|
||||
)
|
||||
if start_marker not in rest:
|
||||
return None, f"start marker not found"
|
||||
idx = rest.index(start_marker)
|
||||
prefix_extra = rest[:idx] # should just be leading whitespace/newline, kept as-is
|
||||
rest = rest[idx + len(start_marker):]
|
||||
|
||||
mid_marker = f'</tag><tag name="_full_{page_name}">'
|
||||
if mid_marker not in rest:
|
||||
return None, f"mid marker not found"
|
||||
mid_idx = rest.index(mid_marker)
|
||||
rest = rest[mid_idx + len(mid_marker):]
|
||||
|
||||
end_pattern = re.compile(
|
||||
r'</tag><if value1="\$\[fragflag\]" value2="1" type="eq">'
|
||||
rf'<_frag_{re.escape(page_name)} /><else><_full_{re.escape(page_name)} /></if>\s*$'
|
||||
)
|
||||
m = end_pattern.search(rest)
|
||||
if not m:
|
||||
return None, f"end marker not found"
|
||||
full_content = rest[:m.start()]
|
||||
|
||||
full_content, nscript = strip_dead_spa_script(full_content)
|
||||
|
||||
result = api_line + "\n" + prefix_extra + full_content
|
||||
return result, f"ok (removed {nscript} dead script block(s))"
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) != 4:
|
||||
print("usage: strip_fragments.py <input> <output> <page_name>")
|
||||
sys.exit(1)
|
||||
with open(sys.argv[1], encoding="utf-8", newline="") as f:
|
||||
content = f.read()
|
||||
result, status = strip_fragment_wrapper(content, sys.argv[3])
|
||||
if result is None:
|
||||
print(f"FAILED for {sys.argv[3]}: {status}")
|
||||
sys.exit(1)
|
||||
with open(sys.argv[2], "w", encoding="utf-8", newline="") as f:
|
||||
f.write(result)
|
||||
print(f"{sys.argv[3]}: {status} ({len(content)} -> {len(result)} bytes)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user