From: Thomas Walker Lynch Date: Sun, 28 Jun 2026 11:47:06 +0000 (+0000) Subject: refactoring outer structure X-Git-Url: https://git.reasoningtechnology.com/%28%5B%5E?a=commitdiff_plain;h=cb0e4dfadf420408dfe7814f6294a71ae2a865c7;p=RT-Style refactoring outer structure --- diff --git a/developer/authored/Manuscript.copy/Core/RT-Style_make.js b/developer/authored/Manuscript.copy/Core/RT-Style_make.js new file mode 100644 index 0000000..ea53313 --- /dev/null +++ b/developer/authored/Manuscript.copy/Core/RT-Style_make.js @@ -0,0 +1,214 @@ +// Core/loader.js + +window.RT = window.RT || {}; +window.RT.Element = []; +window.RT.Module = window.RT.Module || new Set(); + + + +// 2. Establish the Debug System +window.RT.debug = { + active_tokens: new Set([ + 'scroll' + ]), + + log: function(token, message) { + if (this.active_tokens.has(token)) { + console.log(`[RT:${token}]`, message); + } + }, + + warn: function(token, message) { + if (this.active_tokens.has(token)) { + console.warn(`[RT:${token}]`, message); + } + }, + + error: function(token, message) { + console.error(`[RT:${token}] CRITICAL:`, message); + }, + + enable: function(token) { this.active_tokens.add(token); console.log(`Enabled: ${token}`); }, + disable: function(token) { this.active_tokens.delete(token); console.log(`Disabled: ${token}`); } +}; + +// 3. Establish the Utilities +window.RT.utility = { + + string: { + to_roman: function(num) { + if (num < 1) return num.toString(); + const lookup = {M:1000, CM:900, D:500, CD:400, C:100, XC:90, L:50, XL:40, X:10, IX:9, V:5, IV:4, I:1}; + let roman = ''; + for (let i in lookup) { + while (num >= lookup[i]) { + roman += i; + num -= lookup[i]; + } + } + return roman; + }, + + strip_common_indent: function(text, tag_indent = '') { + const raw_lines = text.split('\n'); + const content_lines = raw_lines.filter(line => line.trim().length > 0); + let common_indent = ''; + + if (content_lines.length > 0) { + const first_match = content_lines[0].match(/^\s*/); + common_indent = first_match ? first_match[0] : ''; + + for (let i = 1; i < content_lines.length; i++) { + const line = content_lines[i]; + let j = 0; + while (j < common_indent.length && j < line.length && common_indent[j] === line[j]) { + j++; + } + common_indent = common_indent.substring(0, j); + if (common_indent.length === 0) break; + } + } + + let final_string = ''; + if (common_indent.length > 0 && common_indent.startsWith(tag_indent)) { + const cleaned_lines = raw_lines.map(line => { + return line.startsWith(common_indent) ? line.replace(common_indent, '') : line; + }); + + if (cleaned_lines.length > 0 && cleaned_lines[0].length === 0) { + cleaned_lines.shift(); + } + if (cleaned_lines.length > 0 && cleaned_lines[cleaned_lines.length - 1].trim().length === 0) { + cleaned_lines.pop(); + } + final_string = cleaned_lines.join('\n'); + } else { + final_string = text.trim(); + } + + return final_string; + } + }, + + dom: { + measure_outer_height: function(el) { + const wasInDOM = el.parentNode !== null; + if (!wasInDOM) document.body.appendChild(el); + const rect = el.getBoundingClientRect(); + const style = window.getComputedStyle(el); + const margin = parseFloat(style.marginTop) + parseFloat(style.marginBottom); + if (!wasInDOM) el.remove(); + return (rect.height || 0) + (margin || 0); + }, + + is_block_content: function(element) { + return element.textContent.trim().includes('\n'); + } + }, + + font: { + measure_ink_ratio: function(target_font, ref_font = null) { + const debug = window.RT.debug; + debug.log('layout', `Measuring ink ratio for ${target_font}`); + + const canvas = document.createElement('canvas'); + const ctx = canvas.getContext('2d'); + + if (!ref_font) { + const bodyStyle = window.getComputedStyle(document.body); + ref_font = bodyStyle.fontFamily; + } + + const get_metrics = (font) => { + ctx.font = '100px ' + font; + const metrics = ctx.measureText('M'); + return { + ascent: metrics.actualBoundingBoxAscent, + descent: metrics.actualBoundingBoxDescent + }; + }; + + const ref_m = get_metrics(ref_font); + const target_m = get_metrics(target_font); + + const ratio = ref_m.ascent / target_m.ascent; + + return { + ratio: ratio, + baseline_diff: ref_m.descent - target_m.descent + }; + } + }, + + color: { + extract_l: function(color_string) { + const str = String(color_string).trim(); + + if (!str.startsWith('oklch')) { + console.error(`[RT:color] Invalid format: Expected oklch color string, received '${str}'`); + return 0; + } + + const match = str.match(/oklch\(\s*([\d.]+%?)/); + if (!match) { + console.error(`[RT:color] Parsing error: Could not extract lightness from '${str}'`); + return 0; + } + + const l_value = match[1]; + return l_value.includes('%') ? parseFloat(l_value) / 100 : parseFloat(l_value); + }, + + is_high_contrast: function(bg_color, text_color) { + const bg_l = this.extract_l(bg_color); + const text_l = this.extract_l(text_color); + return Math.abs(text_l - bg_l) >= 0.7; + }, + + is_readable: function(bg_color, text_color) { + const bg_l = this.extract_l(bg_color); + const text_l = this.extract_l(text_color); + return Math.abs(text_l - bg_l) >= 0.5; + }, + + is_light: function(color_string) { + return this.extract_l(color_string) > 0.75; + }, + + is_gray: function(color_string) { + const l = this.extract_l(color_string); + return l >= 0.25 && l <= 0.75; + }, + + is_dark: function(color_string) { + return this.extract_l(color_string) < 0.25; + } + } + +}; + +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; + } + window.RT.Module.add(module_path); + + let resolved_path = window.RT.dirpr_library + '/' + module_path; + if (!resolved_path.endsWith('.js')) { + resolved_path = resolved_path + '.js'; + } + + 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/loader.js b/developer/authored/Manuscript.copy/Core/loader.js deleted file mode 100644 index 171e6d3..0000000 --- a/developer/authored/Manuscript.copy/Core/loader.js +++ /dev/null @@ -1,312 +0,0 @@ -// Core/loader.js - -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 -window.RT.debug = { - active_tokens: new Set([ - 'scroll' - ]), - - log: function(token, message) { - if (this.active_tokens.has(token)) { - console.log(`[RT:${token}]`, message); - } - }, - - warn: function(token, message) { - if (this.active_tokens.has(token)) { - console.warn(`[RT:${token}]`, message); - } - }, - - error: function(token, message) { - console.error(`[RT:${token}] CRITICAL:`, message); - }, - - enable: function(token) { this.active_tokens.add(token); console.log(`Enabled: ${token}`); }, - disable: function(token) { this.active_tokens.delete(token); console.log(`Disabled: ${token}`); } -}; - -// 3. Establish the Utilities -window.RT.utility = { - - string: { - to_roman: function(num) { - if (num < 1) return num.toString(); - const lookup = {M:1000, CM:900, D:500, CD:400, C:100, XC:90, L:50, XL:40, X:10, IX:9, V:5, IV:4, I:1}; - let roman = ''; - for (let i in lookup) { - while (num >= lookup[i]) { - roman += i; - num -= lookup[i]; - } - } - return roman; - }, - - strip_common_indent: function(text, tag_indent = '') { - const raw_lines = text.split('\n'); - const content_lines = raw_lines.filter(line => line.trim().length > 0); - let common_indent = ''; - - if (content_lines.length > 0) { - const first_match = content_lines[0].match(/^\s*/); - common_indent = first_match ? first_match[0] : ''; - - for (let i = 1; i < content_lines.length; i++) { - const line = content_lines[i]; - let j = 0; - while (j < common_indent.length && j < line.length && common_indent[j] === line[j]) { - j++; - } - common_indent = common_indent.substring(0, j); - if (common_indent.length === 0) break; - } - } - - let final_string = ''; - if (common_indent.length > 0 && common_indent.startsWith(tag_indent)) { - const cleaned_lines = raw_lines.map(line => { - return line.startsWith(common_indent) ? line.replace(common_indent, '') : line; - }); - - if (cleaned_lines.length > 0 && cleaned_lines[0].length === 0) { - cleaned_lines.shift(); - } - if (cleaned_lines.length > 0 && cleaned_lines[cleaned_lines.length - 1].trim().length === 0) { - cleaned_lines.pop(); - } - final_string = cleaned_lines.join('\n'); - } else { - final_string = text.trim(); - } - - return final_string; - } - }, - - dom: { - measure_outer_height: function(el) { - const wasInDOM = el.parentNode !== null; - if (!wasInDOM) document.body.appendChild(el); - const rect = el.getBoundingClientRect(); - const style = window.getComputedStyle(el); - const margin = parseFloat(style.marginTop) + parseFloat(style.marginBottom); - if (!wasInDOM) el.remove(); - return (rect.height || 0) + (margin || 0); - }, - - is_block_content: function(element) { - return element.textContent.trim().includes('\n'); - } - }, - - font: { - measure_ink_ratio: function(target_font, ref_font = null) { - const debug = window.RT.debug; - debug.log('layout', `Measuring ink ratio for ${target_font}`); - - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - - if (!ref_font) { - const bodyStyle = window.getComputedStyle(document.body); - ref_font = bodyStyle.fontFamily; - } - - const get_metrics = (font) => { - ctx.font = '100px ' + font; - const metrics = ctx.measureText('M'); - return { - ascent: metrics.actualBoundingBoxAscent, - descent: metrics.actualBoundingBoxDescent - }; - }; - - const ref_m = get_metrics(ref_font); - const target_m = get_metrics(target_font); - - const ratio = ref_m.ascent / target_m.ascent; - - return { - ratio: ratio, - baseline_diff: ref_m.descent - target_m.descent - }; - } - }, - - color: { - extract_l: function(color_string) { - const str = String(color_string).trim(); - - if (!str.startsWith('oklch')) { - console.error(`[RT:color] Invalid format: Expected oklch color string, received '${str}'`); - return 0; - } - - const match = str.match(/oklch\(\s*([\d.]+%?)/); - if (!match) { - console.error(`[RT:color] Parsing error: Could not extract lightness from '${str}'`); - return 0; - } - - const l_value = match[1]; - return l_value.includes('%') ? parseFloat(l_value) / 100 : parseFloat(l_value); - }, - - is_high_contrast: function(bg_color, text_color) { - const bg_l = this.extract_l(bg_color); - const text_l = this.extract_l(text_color); - return Math.abs(text_l - bg_l) >= 0.7; - }, - - is_readable: function(bg_color, text_color) { - const bg_l = this.extract_l(bg_color); - const text_l = this.extract_l(text_color); - return Math.abs(text_l - bg_l) >= 0.5; - }, - - is_light: function(color_string) { - return this.extract_l(color_string) > 0.75; - }, - - is_gray: function(color_string) { - const l = this.extract_l(color_string); - return l >= 0.25 && l <= 0.75; - }, - - is_dark: function(color_string) { - return this.extract_l(color_string) < 0.25; - } - } - -}; - -window.RT.load = function(module_path) { - if (window.RT.Module.has(module_path)) { - return; - } - window.RT.Module.add(module_path); - - let resolved_path = window.RT.dirpr_library + '/' + module_path; - if (!resolved_path.endsWith('.js')) { - resolved_path = resolved_path + '.js'; - } - - document.write(''); -}; 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( '