From cb0e4dfadf420408dfe7814f6294a71ae2a865c7 Mon Sep 17 00:00:00 2001 From: Thomas Walker Lynch Date: Sun, 28 Jun 2026 11:47:06 +0000 Subject: [PATCH] refactoring outer structure --- .../Core/{loader.js => RT-Style_make.js} | 122 +------ .../Core/block_visibility_during_layout.js | 19 -- .../Manuscript.copy/Core/document_loaded.js | 24 -- .../Manuscript.copy/Core/stage_manager.js | 143 ++++++++ .../Manuscript.copy/Core/theme_make.js | 101 ++++++ .../Document/RT-Style_locator.js | 8 +- .../Manuscript.copy/Document/RT-style.js | 20 -- .../Manuscript.copy/Document/manual.html | 4 +- .../Manuscript.copy/Element/theme_selector.js | 48 +-- .../Layout/article_tech_ref.js | 315 ++++++++---------- .../Manuscript.copy/Locator/direct.js | 2 - .../Manuscript.copy/Theme/golden_wheat.js | 153 ++++----- .../Manuscript.copy/Theme/inverse_wheat.js | 142 +++----- .../Manuscript.copy/Theme/manifest.js | 16 + .../authored/Manuscript.copy/Theme/wheat.js | 138 +++----- 15 files changed, 596 insertions(+), 659 deletions(-) rename developer/authored/Manuscript.copy/Core/{loader.js => RT-Style_make.js} (63%) delete mode 100644 developer/authored/Manuscript.copy/Core/block_visibility_during_layout.js delete mode 100644 developer/authored/Manuscript.copy/Core/document_loaded.js create mode 100644 developer/authored/Manuscript.copy/Core/stage_manager.js create mode 100644 developer/authored/Manuscript.copy/Core/theme_make.js delete mode 100644 developer/authored/Manuscript.copy/Document/RT-style.js create mode 100644 developer/authored/Manuscript.copy/Theme/manifest.js diff --git a/developer/authored/Manuscript.copy/Core/loader.js b/developer/authored/Manuscript.copy/Core/RT-Style_make.js similarity index 63% rename from developer/authored/Manuscript.copy/Core/loader.js rename to developer/authored/Manuscript.copy/Core/RT-Style_make.js index 171e6d3..ea53313 100644 --- a/developer/authored/Manuscript.copy/Core/loader.js +++ b/developer/authored/Manuscript.copy/Core/RT-Style_make.js @@ -4,116 +4,6 @@ window.RT = window.RT || {}; window.RT.Element = []; window.RT.Module = window.RT.Module || new Set(); -// 1. Establish the Generic Theme Dictionary -// e.g. RT.theme( 'read', 'content_main') -window.RT.theme = (function() { - const dictionary = { - meta: { - is_dark: false, - name: "" - }, - surface: { - 0: "", 1: "", 2: "", 3: "", - input: "", code: "", select: "" - }, - content: { - main: "", muted: "", subtle: "", inverse: "" - }, - brand: { - primary: "", secondary: "", tertiary: "", link: "" - }, - border: { - faint: "", regular: "", strong: "" - }, - state: { - success: "", warning: "", error: "", info: "" - }, - syntax: { - keyword: "", string: "", func: "", comment: "" - }, - page: { - width: "", min_height: "", padding: "", margin: "", - bg_color: "", border_color: "", text_color: "", shadow: "" - } - }; - - function resolve_path(path_array) { - let current = dictionary; - for (let i = 0; i < path_array.length - 1; i++) { - const step = path_array[i]; - if (current[step] === undefined) return null; - current = current[step]; - } - return { container: current, key: path_array[path_array.length - 1] }; - } - - function check_completion(obj, path_string) { - for (const key in obj) { - if (typeof obj[key] === 'object' && obj[key] !== null) { - if (!check_completion(obj[key], path_string + key + '.')) { - return false; - } - } else { - if (obj[key] === "") { - window.RT.debug.error('theme', 'is_defined check failed at missing key: ' + path_string + key); - return false; - } - } - } - return true; - } - - return function(command, ...args) { - - // e.g. RT.theme('read','page','width') - if (command === 'read') { - const target = resolve_path(args); - if (target && target.container.hasOwnProperty(target.key)) { - return target.container[target.key]; - } - window.RT.debug.error('theme', 'Read attempt on unknown path: ' + args.join('.')); - return null; - } - - if (command === 'write') { - if (args.length < 2) { - window.RT.debug.error('theme', 'Write command expects a path and a value.'); - return; - } - const value = args.pop(); - const target = resolve_path(args); - - if (target && target.container.hasOwnProperty(target.key)) { - target.container[target.key] = value; - } else { - window.RT.debug.error('theme', 'Write attempt on unknown path rejected: ' + args.join('.')); - } - return; - } - - if (command === 'is_defined') { - if (args.length === 0) { - return check_completion(dictionary, ''); - } - - for (let i = 0; i < args.length; i++) { - const path_array = args[i]; - if (!Array.isArray(path_array)) { - window.RT.debug.error('theme', 'is_defined arguments must be path arrays. Received: ' + path_array); - return false; - } - const target = resolve_path(path_array); - if (!target || !target.container.hasOwnProperty(target.key) || target.container[target.key] === "") { - window.RT.debug.error('theme', 'is_defined check failed at: ' + path_array.join('.')); - return false; - } - } - return true; - } - - window.RT.debug.error('theme', 'Invalid command passed to theme dictionary: ' + command); - }; -})(); // 2. Establish the Debug System @@ -297,6 +187,14 @@ window.RT.utility = { }; +window.RT.theme_preference = function(author_pref, default_color = "#FF00FF") { + const reader_pref = localStorage.getItem('RT-Style·theme_preference'); + const theme_to_load = reader_pref ? reader_pref : author_pref; + + window.RT.theme('load', theme_to_load, default_color); +}; + + window.RT.load = function(module_path) { if (window.RT.Module.has(module_path)) { return; @@ -310,3 +208,7 @@ window.RT.load = function(module_path) { document.write(''); }; + +window.RT.load('Core/stage_manager'); +window.RT.load('Core/theme_make'); +window.RT.load('Theme/manifest.js') diff --git a/developer/authored/Manuscript.copy/Core/block_visibility_during_layout.js b/developer/authored/Manuscript.copy/Core/block_visibility_during_layout.js deleted file mode 100644 index 8513f01..0000000 --- a/developer/authored/Manuscript.copy/Core/block_visibility_during_layout.js +++ /dev/null @@ -1,19 +0,0 @@ -// block_visibility_during_layout.js - -// 1. Hide the document immediately upon execution in the -document.documentElement.style.visibility = "hidden"; - -// 2. Define the restoration function -const restore_visibility = function() { - document.documentElement.style.visibility = ""; - document.removeEventListener("RT_layout_complete", restore_visibility); - window.removeEventListener("load", restore_visibility); -}; - -// 3. Listen for a specific completion signal from the layout engine -document.addEventListener("RT_layout_complete", restore_visibility); - -// 4. Structural Safety Net: If the layout engine fails or is never loaded, -// restore visibility on the final window 'load' event so the page doesn't remain blank. -window.addEventListener("load", restore_visibility); - diff --git a/developer/authored/Manuscript.copy/Core/document_loaded.js b/developer/authored/Manuscript.copy/Core/document_loaded.js deleted file mode 100644 index e12641d..0000000 --- a/developer/authored/Manuscript.copy/Core/document_loaded.js +++ /dev/null @@ -1,24 +0,0 @@ -window.RT = window.RT || {}; - -window.RT.document_loaded = function(layout_callback) { - const debug = window.RT.debug || { log: function(){} }; - debug.log('lifecycle', 'Processing registered elements.'); - - if (window.RT.theme) { - window.RT.theme(); - } - - if (window.RT.Element && Array.isArray(window.RT.Element)) { - window.RT.Element.forEach(function(element_fn) { - if (typeof element_fn === 'function') { - element_fn(); - } - }); - } - - if (window.MathJax && MathJax.Hub && MathJax.Hub.Queue) { - MathJax.Hub.Queue(["Typeset", MathJax.Hub], layout_callback); - } else { - layout_callback(); - } -}; diff --git a/developer/authored/Manuscript.copy/Core/stage_manager.js b/developer/authored/Manuscript.copy/Core/stage_manager.js new file mode 100644 index 0000000..e1057cb --- /dev/null +++ b/developer/authored/Manuscript.copy/Core/stage_manager.js @@ -0,0 +1,143 @@ +// Core/document_loaded.js + +window.RT = window.RT || {}; +window.RT.Element = window.RT.Element || []; +window.RT.Module = window.RT.Module || new Set(); + +(function(){ + const debug = window.RT.debug || { log: function(){} }; + + let target_y = 0; + let is_reload = false; + let is_layout_locked = false; + let scroll_timer; + + function lock_layout() { + is_layout_locked = true; + document.documentElement.style.visibility = "hidden"; + } + + function unlock_layout() { + if (!is_layout_locked) return; + is_layout_locked = false; + + document.documentElement.style.visibility = ""; + window.removeEventListener("load", unlock_layout); + document.dispatchEvent(new Event("RT_layout_complete")); + } + + function configure_history(){ + if ('scrollRestoration' in history) { + history.scrollRestoration = 'manual'; + } + } + + function capture_scroll_target(){ + const raw_target = sessionStorage.getItem('RT_saved_y'); + target_y = raw_target !== null ? parseInt(raw_target ,10) : 0; + + if (window.performance) { + const nav_entries = performance.getEntriesByType("navigation"); + if (nav_entries.length > 0) { + is_reload = (nav_entries[0].type === "reload"); + } else if (performance.navigation) { + is_reload = (performance.navigation.type === 1); + } + } + } + + function enforce_scroll(target ,use_hash ,attempts){ + if (attempts > 15) { + unlock_layout(); + return; + } + + if (use_hash) { + const hash_target = document.getElementById(window.location.hash.substring(1)); + if (hash_target) { + hash_target.scrollIntoView(); + } + } else { + window.scrollTo(0 ,target); + } + + let is_successful = use_hash ? true : (Math.abs(window.scrollY - target) < 5 || target === 0); + if (is_successful && document.body.scrollHeight > 1000) { + setTimeout(() => { + if (!use_hash && Math.abs(window.scrollY - target) >= 5) { + enforce_scroll(target ,use_hash ,attempts + 1); + } else { + unlock_layout(); + } + }, 100); + } else { + setTimeout(() => enforce_scroll(target ,use_hash ,attempts + 1) ,50); + } + } + + function bind_window_events(){ + window.addEventListener('scroll' ,() => { + if (is_layout_locked) return; + clearTimeout(scroll_timer); + scroll_timer = setTimeout(() => { + sessionStorage.setItem('RT_saved_y' ,window.scrollY); + }, 200); + }, { passive: true }); + + window.addEventListener('beforeunload' ,() => { + lock_layout(); + }); + } + + function execute_pagination_and_scroll(){ + debug.log('scroll' ,`Pagination layout starting.`); + if(window.RT.paginate_by_element) window.RT.paginate_by_element(); + if(window.RT.page) window.RT.page(); + + let final_target = target_y; + let use_hash = false; + if (window.location.hash && !is_reload) { + const hash_target = document.getElementById(window.location.hash.substring(1)); + if (hash_target) { + use_hash = true; + } + } + + enforce_scroll(final_target ,use_hash ,0); + } + + function process_elements_and_layout() { + debug.log('lifecycle', 'Processing registered elements.'); + + if (window.RT.theme) { + window.RT.theme(); + } + + if (window.RT.Element && Array.isArray(window.RT.Element)) { + while (window.RT.Element.length > 0) { + const element_fn = window.RT.Element.shift(); + if (typeof element_fn === 'function') { + element_fn(); + } + } + } + + if (window.MathJax && MathJax.Hub && MathJax.Hub.Queue) { + MathJax.Hub.Queue(["Typeset", MathJax.Hub], execute_pagination_and_scroll); + } else { + execute_pagination_and_scroll(); + } + } + + // Initial Execution + lock_layout(); + configure_history(); + capture_scroll_target(); + bind_window_events(); + + document.addEventListener('DOMContentLoaded', process_elements_and_layout); + + // Structural Safety Net: restore visibility on load if layout engine hangs + window.addEventListener("load", unlock_layout); + +})(); diff --git a/developer/authored/Manuscript.copy/Core/theme_make.js b/developer/authored/Manuscript.copy/Core/theme_make.js new file mode 100644 index 0000000..eea792a --- /dev/null +++ b/developer/authored/Manuscript.copy/Core/theme_make.js @@ -0,0 +1,101 @@ +// 1. Establish the Generic Theme Dictionary +// e.g. RT.theme( 'read', 'content_main') +// Establish the global theme library +window.RT.theme_library = window.RT.theme_library || {}; + +window.RT.theme = (function() { + const dictionary = { + meta: { is_dark: false, name: "" }, + surface: { 0: "", 1: "", 2: "", 3: "", input: "", code: "", select: "" }, + content: { main: "", muted: "", subtle: "", inverse: "" }, + brand: { primary: "", secondary: "", tertiary: "", link: "" }, + border: { faint: "", regular: "", strong: "" }, + state: { success: "", warning: "", error: "", info: "" }, + syntax: { keyword: "", string: "", func: "", comment: "" }, + page: { width: "", min_height: "", padding: "", margin: "", bg_color: "", border_color: "", text_color: "", shadow: "" } + }; + + function resolve_path(path_array) { + let current = dictionary; + for (let i = 0; i < path_array.length - 1; i++) { + const step = path_array[i]; + if (current[step] === undefined) return null; + current = current[step]; + } + return { container: current, key: path_array[path_array.length - 1] }; + } + + function apply_and_validate_theme(new_theme, fallback_color) { + const debug = window.RT.debug || { error: function(){} }; + + // Pass 1: Walk the structure of the active dictionary + function walk_current(curr, source, path) { + for (const key in curr) { + const current_path = path ? path + "." + key : key; + if (typeof curr[key] === 'object' && curr[key] !== null) { + walk_current(curr[key], source[key] || {}, current_path); + } else { + if (source[key] !== undefined && source[key] !== "") { + curr[key] = source[key]; + } else { + debug.error('theme', `Missing key in loaded theme: ${current_path}. Assigning fallback.`); + curr[key] = fallback_color; + } + } + } + } + + // Pass 2: Walk the structure of the incoming theme dictionary + function walk_new(source, curr, path) { + for (const key in source) { + const current_path = path ? path + "." + key : key; + if (typeof source[key] === 'object' && source[key] !== null) { + if (curr[key] === undefined) { + debug.error('theme', `Unexpected structure in loaded theme: ${current_path} is an object.`); + } else { + walk_new(source[key], curr[key] || {}, current_path); + } + } else { + if (curr[key] === undefined) { + debug.error('theme', `Unexpected key in loaded theme: ${current_path}.`); + } + } + } + } + + walk_current(dictionary, new_theme, ""); + walk_new(new_theme, dictionary, ""); + } + + return function(command, ...args) { + if (command === 'read') { + const target = resolve_path(args); + return (target && target.container.hasOwnProperty(target.key)) ? target.container[target.key] : null; + } + + if (command === 'write') { + if (args.length < 2) return; + const value = args.pop(); + const target = resolve_path(args); + if (target && target.container.hasOwnProperty(target.key)) { + target.container[target.key] = value; + } + return; + } + + if (command === 'load') { + const theme_name = args[0]; + const fallback = args[1] || "#FF00FF"; + + if (!window.RT.theme_library.hasOwnProperty(theme_name)) { + window.RT.debug.error('theme', `Load aborted: Theme '${theme_name}' is not in the theme_library.`); + return false; + } + + apply_and_validate_theme(window.RT.theme_library[theme_name], fallback); + return true; + } + + window.RT.debug.error('theme', 'Invalid command passed to theme dictionary: ' + command); + }; +})(); diff --git a/developer/authored/Manuscript.copy/Document/RT-Style_locator.js b/developer/authored/Manuscript.copy/Document/RT-Style_locator.js index 0fac1e3..b8dd367 100644 --- a/developer/authored/Manuscript.copy/Document/RT-Style_locator.js +++ b/developer/authored/Manuscript.copy/Document/RT-Style_locator.js @@ -13,18 +13,12 @@ window.RT = window.RT || {}; (function() { - // We are the style library, so ... window.RT.dirpr_library = ".."; - - // 1. Inject the loader script - document.write(' - - { - let current_theme = localStorage.getItem('RT_theme_preference'); - if(!current_theme){ - current_theme = 'dark_gold'; - } +window.RT.Element.push(function build_theme_selector() { + document.querySelectorAll('rt·theme-selector').forEach((el) => { + + const active_theme = window.RT.theme('read', 'meta', 'name'); + const available_themes = Object.keys(window.RT.theme_library || {}); const container = document.createElement('div'); container.style.position = 'fixed'; @@ -18,23 +20,31 @@ window.RT.theme_selector = function(){ container.style.color = 'white'; container.style.fontFamily = 'sans-serif'; - container.innerHTML = ` - Theme Selection
-
- - `; + let html_content = `Theme Selection
`; + + if (available_themes.length === 0) { + html_content += `No themes found in library.`; + } else { + available_themes.forEach(theme_name => { + const is_checked = active_theme === theme_name ? 'checked' : ''; + html_content += ` +
+ `; + }); + } + + container.innerHTML = html_content; - container.addEventListener( 'change' ,(e) => { + container.addEventListener('change', (e) => { if(e.target.name === 'RT·theme') { - localStorage.setItem('RT_theme_preference' ,e.target.value); - location.reload(); + localStorage.setItem('RT-Style·theme_preference', e.target.value); + // Reloading applies the new preference via theme_preference() in the + location.reload(); } }); el.replaceWith(container); }); -}; +}); diff --git a/developer/authored/Manuscript.copy/Layout/article_tech_ref.js b/developer/authored/Manuscript.copy/Layout/article_tech_ref.js index ffc9420..d015b0d 100644 --- a/developer/authored/Manuscript.copy/Layout/article_tech_ref.js +++ b/developer/authored/Manuscript.copy/Layout/article_tech_ref.js @@ -1,201 +1,156 @@ (function(){ const RT = window.RT = window.RT || {}; - const debug = RT.debug || { log: function(){} }; - let target_y = 0; - let is_reload = false; - let is_layout_locked = true; - let scroll_timer; - - function configure_history(){ - if ('scrollRestoration' in history) { - history.scrollRestoration = 'manual'; - } - } - - function capture_scroll_target(){ - const raw_target = sessionStorage.getItem('RT_saved_y'); - target_y = raw_target !== null ? parseInt(raw_target ,10) : 0; - - if (window.performance) { - const nav_entries = performance.getEntriesByType("navigation"); - if (nav_entries.length > 0) { - is_reload = (nav_entries[0].type === "reload"); - } else if (performance.navigation) { - is_reload = (performance.navigation.type === 1); - } - } - } - - function load_elements(){ - // The specific elements requested by the layout - RT.load('Element/counter'); - RT.load('Element/chapter'); - RT.load('Element/endnote'); - RT.load('Element/math'); - RT.load('Element/code'); - RT.load('Element/term'); - RT.load('Element/TOC'); - RT.load('Element/title'); - RT.load('Element/symbol'); - RT.load('Element/constraint'); - RT.load('Element/crossref'); - - RT.load('Layout/paginate_by_element'); - RT.load('Layout/page_fixed_glow'); - } - - function apply_style_rule(selector ,rules){ - document.querySelectorAll(selector).forEach( (el) => { - for (let prop in rules) { - if (typeof rules[prop] === 'string' && rules[prop].indexOf('!important') !== -1) { - const kebab_prop = prop.replace(/[A-Z]/g ,m => "-" + m.toLowerCase()); - const value = rules[prop].replace(' !important' ,''); - el.style.setProperty(kebab_prop ,value ,'important'); - } else { - el.style[prop] = rules[prop]; + // 1. The Explicit Element Roster + const required_elements = [ + 'counter', + 'chapter', + 'endnote', + 'math', + 'code', + 'term', + 'TOC', + 'title', + 'symbol', + 'constraint', + 'crossref' + ]; + + // Trigger file loading immediately + required_elements.forEach(name => RT.load('Element/' + name)); + + // 2. The Extracted Styling Function + function apply_article_styles() { + const t = function(...path) { return window.RT.theme('read', ...path); }; + + const surface_0 = t('surface', '0'); + const surface_code = t('surface', 'code'); + const content_main = t('content', 'main'); + const brand_primary = t('brand', 'primary'); + const brand_secondary = t('brand', 'secondary'); + const brand_tertiary = t('brand', 'tertiary'); + const is_dark = t('meta', 'is_dark'); + + const font_weight = is_dark === false ? "600" : "400"; + + const apply = function(selector, rules) { + document.querySelectorAll(selector).forEach(el => { + for (let p in rules) { + if (typeof rules[p] === 'string' && rules[p].includes('!important')) { + el.style.setProperty(p.replace(/[A-Z]/g, m => "-" + m.toLowerCase()), rules[p].replace(' !important', ''), 'important'); + } else { + el.style[p] = rules[p]; + } } - } - }); - } - - function apply_style(){ - // Note: This will be updated to read from window.RT.theme('read', ...) - // in the next iteration. - RT.config = RT.config || {}; - RT.config.article = { - font_family: "'Noto Sans JP', Arial, sans-serif" - ,line_height: "1.8" - ,font_size: "16px" - ,font_weight: "400" - ,max_width: "46.875rem" - ,margin: "0 auto" + }); }; - - if( RT.config.theme && RT.config.theme.meta_is_dark === false ){ - RT.config.article.font_weight = "600"; - } - window.RT.config.page = window.RT.config.page || {}; - window.RT.config.page.height_limit = 900; - - const conf = RT.config.article; - - apply_style_rule('body, html, RT·article' ,{ overflowAnchor: "none !important" }); - apply_style_rule('RT·article', { + // Apply base geometry + apply('body, html, RT·article', { overflowAnchor: "none !important" }); + apply('RT·article', { display: "block", - fontFamily: conf.font_family, - fontSize: conf.font_size, - lineHeight: conf.line_height, - fontWeight: conf.font_weight, - maxWidth: conf.max_width + " !important", - margin: conf.margin, - backgroundColor: RT.config.theme.surface_0, - color: RT.config.theme.content_main, + fontFamily: "'Noto Sans JP', Arial, sans-serif", + fontSize: "16px", + lineHeight: "1.8", + fontWeight: font_weight, + maxWidth: "46.875rem !important", + margin: "0 auto", + backgroundColor: surface_0, + color: content_main, boxSizing: "border-box !important" }); - apply_style_rule('RT·article:not(:has(RT·page))' ,{ padding: "3rem !important" }); - apply_style_rule('RT·article:has(RT·page)' ,{ padding: "0 !important" }); - apply_style_rule('RT·article RT·page' ,{ - position: "relative", - display: "block", - padding: "3rem", - margin: "1.25rem auto", - backgroundColor: RT.config.theme.surface_0, - boxShadow: `0 0 0.625rem ${RT.config.theme.brand_primary}` + apply('RT·article:not(:has(RT·page))', { padding: "3rem !important" }); + apply('RT·article:has(RT·page)', { padding: "0 !important" }); + apply('RT·article RT·page', { + position: "relative", display: "block", padding: "3rem", + margin: "1.25rem auto", backgroundColor: surface_0, + boxShadow: `0 0 0.625rem ${brand_primary}` }); - apply_style_rule('RT·article h1' ,{ fontSize: "1.5rem", textAlign: "center", color: RT.config.theme.brand_primary, fontWeight: "500", marginTop: "1.5rem", lineHeight: "1.15" }); - apply_style_rule('RT·article h2' ,{ fontSize: "1.25rem", color: RT.config.theme.brand_secondary, textAlign: "left", marginTop: "2rem", marginLeft: "0" }); - apply_style_rule('RT·article h3' ,{ fontSize: "1.125rem", color: RT.config.theme.brand_tertiary, textAlign: "left", marginTop: "1.5rem", marginLeft: "4ch" }); - apply_style_rule('RT·article h4' ,{ fontSize: "1.05rem", color: RT.config.theme.content_main, fontWeight: "600", textAlign: "left", marginTop: "1.25rem", marginLeft: "8ch" }); - apply_style_rule('RT·article p, RT·article ul, RT·article ol' ,{ color: RT.config.theme.content_main, textAlign: "justify", marginBottom: "1rem", marginLeft: "0" }); - apply_style_rule('RT·article li' ,{ marginBottom: "0.5rem" }); - apply_style_rule('RT·article RT·code' ,{ fontFamily: "'Courier New', Courier, monospace", backgroundColor: RT.config.theme.surface_code, padding: "0.125rem 0.25rem", color: RT.config.theme.content_main }); - apply_style_rule('RT·article img' ,{ maxWidth: "100%", height: "auto", display: "block", margin: "1.5rem auto" }); + // Apply specific element scales + const element_styles = [ + [ 'RT·article h1', { + fontSize: "1.5rem", + textAlign: "center", + color: brand_primary, + fontWeight: "500", + marginTop: "1.5rem", + lineHeight: "1.15" + }], + + [ 'RT·article h2', { + fontSize: "1.25rem", + color: brand_secondary, + textAlign: "left", + marginTop: "2rem", + marginLeft: "0" + }], + + [ 'RT·article h3', { + fontSize: "1.125rem", + color: brand_tertiary, + textAlign: "left", + marginTop: "1.5rem", + marginLeft: "4ch" + }], + + [ 'RT·article h4', { + fontSize: "1.05rem", + color: content_main, + fontWeight: "600", + textAlign: "left", + marginTop: "1.25rem", + marginLeft: "8ch" + }], + + [ 'RT·article p, RT·article ul, RT·article ol', { + color: content_main, + textAlign: "justify", + marginBottom: "1rem", + marginLeft: "0" + }], + + [ 'RT·article li', { + marginBottom: "0.5rem" + }], + + [ 'RT·article RT·code', { + fontFamily: "'Courier New', Courier, monospace", + backgroundColor: surface_code, + padding: "0.125rem 0.25rem", + color: content_main + }], + + [ 'RT·article img', { + maxWidth: "100%", + height: "auto", + display: "block", + margin: "1.5rem auto" + }] + ]; + + element_styles.forEach(rule => apply(rule[0], rule[1])); } - function execute_pagination_and_scroll(){ - debug.log('scroll' ,`8. Pagination layout starting.`); - if(RT.paginate_by_element) RT.paginate_by_element(); - if(RT.page) RT.page(); + // 3. The Core Layout Entry Function + function article_tech_ref(){ - let final_target = target_y; - let use_hash = false; - if (window.location.hash && !is_reload) { - const hash_target = document.getElementById(window.location.hash.substring(1)); - if (hash_target) { - use_hash = true; - } - } - - enforce_scroll(final_target ,use_hash ,0); - } - - function enforce_scroll(target ,use_hash ,attempts){ - if (attempts > 15) { - unlock_layout(); - return; - } - - if (use_hash) { - const hash_target = document.getElementById(window.location.hash.substring(1)); - if (hash_target) { - hash_target.scrollIntoView(); + // Execute the extracted style generator first + apply_article_styles(); + + // Dynamically enqueue the semantic processors + required_elements.forEach(name => { + if (typeof RT[name] === 'function') { + RT.Element.push(RT[name]); + } else { + RT.debug.warn('layout', 'Required element function missing: RT.' + name); } - } else { - window.scrollTo(0 ,target); - } - - let is_successful = use_hash ? true : (Math.abs(window.scrollY - target) < 5 || target === 0); - if (is_successful && document.body.scrollHeight > 1000) { - setTimeout(() => { - if (!use_hash && Math.abs(window.scrollY - target) >= 5) { - enforce_scroll(target ,use_hash ,attempts + 1); - } else { - unlock_layout(); - } - }, 100); - } else { - setTimeout(() => enforce_scroll(target ,use_hash ,attempts + 1) ,50); - } - } - - function unlock_layout(){ - if (!is_layout_locked) return; - is_layout_locked = false; - document.dispatchEvent(new Event("RT_layout_complete")); - } - - function bind_window_events(){ - window.addEventListener('scroll' ,() => { - if (is_layout_locked) return; - clearTimeout(scroll_timer); - scroll_timer = setTimeout(() => { - sessionStorage.setItem('RT_saved_y' ,window.scrollY); - }, 200); - }, { passive: true }); - - window.addEventListener('beforeunload' ,() => { - is_layout_locked = true; }); } - // Execution Outline - configure_history(); - capture_scroll_target(); - load_elements(); - bind_window_events(); - - document.addEventListener('DOMContentLoaded', () => { - apply_style(); - - if (window.RT.document_loaded) { - window.RT.document_loaded(execute_pagination_and_scroll); - } else { - execute_pagination_and_scroll(); - } - }); + // 4. Register the layout function immediately upon parsing + RT.Element = RT.Element || []; + RT.Element.push(article_tech_ref); })(); diff --git a/developer/authored/Manuscript.copy/Locator/direct.js b/developer/authored/Manuscript.copy/Locator/direct.js index 2f93eb7..f9457a5 100644 --- a/developer/authored/Manuscript.copy/Locator/direct.js +++ b/developer/authored/Manuscript.copy/Locator/direct.js @@ -31,9 +31,7 @@ window.RT = window.RT || {}; document.write( '