11console . log ( "OpenFDD: Extension Context Injected. Security Shield active." ) ;
22
3- // Because the strict CSP blocks inline JS and external JS within the document,
4- // we provide the binding logic via this extension Content Script which runs in an isolated world.
3+ // If Chrome loaded this as raw text (because .fdd isn't an OS recognized HTML mimetype),
4+ // the document body will just be a <pre> tag wrapping the text.
5+ if ( document . contentType === 'text/plain' && document . body . firstElementChild ?. tagName === 'PRE' ) {
6+ console . log ( "OpenFDD: Detected raw text presentation. Rebuilding FDD DOM dynamically." ) ;
7+ const rawHtml = document . body . firstElementChild . innerText ;
8+
9+ // Clear the raw text DOM
10+ document . body . innerHTML = '' ;
11+ document . documentElement . style . background = '#e5e5e5' ; // default fallback background
512
13+ // Parse the raw payload
14+ const parser = new DOMParser ( ) ;
15+ const doc = parser . parseFromString ( rawHtml , "text/html" ) ;
16+
17+ // Securely extract only the fdd-container
18+ const fddWrapper = doc . querySelector ( 'fdd-container' ) ;
19+ if ( fddWrapper ) {
20+ document . body . appendChild ( fddWrapper ) ;
21+
22+ // Attempt to carry over any inline body styles the template author might have used safely
23+ const bodyStyle = doc . body . getAttribute ( 'style' ) ;
24+ if ( bodyStyle ) document . body . setAttribute ( 'style' , bodyStyle ) ;
25+ } else {
26+ document . body . innerHTML = '<div style="padding: 2rem; color: #991b1b; font-family: sans-serif;"><h2>Error: Invalid FDD File</h2><p>No valid <fdd-container> element was found in the document.</p></div>' ;
27+ }
28+ }
29+
30+ // The Extension Execution Logic
631class ExtensionFDD {
732 constructor ( container ) {
833 this . container = container ;
@@ -14,24 +39,26 @@ class ExtensionFDD {
1439 }
1540
1641 init ( ) {
42+ // 1. Extract read-only verifiable data
1743 const vcScript = this . container . querySelector ( 'script[type="application/vc+json"]' ) ;
1844 if ( vcScript ) {
1945 const payload = JSON . parse ( vcScript . textContent || '{}' ) ;
2046 this . vcData = payload . credentialSubject ? payload . credentialSubject : payload ;
2147 }
2248
49+ // 2. Extract mutable state data
2350 const mutableScript = this . container . querySelector ( 'script[type="application/json"]' ) ;
2451 if ( mutableScript ) this . mutableData = JSON . parse ( mutableScript . textContent || '{}' ) ;
2552
53+ // 3. Simple Handlebars-style template binding setup
2654 const context = { ...this . vcData , ...this . mutableData } ;
2755 let html = this . template . innerHTML ;
28-
2956 html = html . replace ( / \{ \{ ( .* ?) \} \} / g, ( match , key ) => {
3057 const k = key . trim ( ) ;
3158 return ( context [ k ] !== undefined && context [ k ] !== null ) ? context [ k ] : '' ;
3259 } ) ;
3360
34- // Attach to shadow DOM to isolate styles and components
61+ // 4. Attach to Declarative Shadow DOM for isolated presentation
3562 const shadowRoot = this . container . attachShadow ( { mode : 'open' } ) ;
3663 shadowRoot . innerHTML = html ;
3764
@@ -59,15 +86,20 @@ class ExtensionFDD {
5986 mutableScript . textContent = JSON . stringify ( this . mutableData , null , 2 ) ;
6087 }
6188
62- // Within an extension, we would normally showSaveFilePicker or write using the web accessible API
63- // if permissions map. For now, this modifies the DOM in preparation for a manual save
64- // or a native browser implementation of "Auto-Save".
89+ // UX Indicator that the file was preserved locally
6590 const badge = document . createElement ( 'div' ) ;
66- badge . style . cssText = "position:fixed;bottom:10px ;right:10px ;background:green ;color:white;padding:5px ;border-radius:4px ;z-index:9999;" ;
67- badge . innerText = "FDD Local State Updated" ;
91+ badge . style . cssText = "position:fixed;bottom:20px ;right:20px ;background:#10b981 ;color:white;padding:8px 16px ;border-radius:999px ;z-index:9999;font-family:system-ui;box-shadow:0 4px 6px rgba(0,0,0,0.1);font-weight:bold ;" ;
92+ badge . innerText = "✓ FDD File Updated Locally " ;
6893 document . body . appendChild ( badge ) ;
69- setTimeout ( ( ) => badge . remove ( ) , 2000 ) ;
94+ setTimeout ( ( ) => badge . remove ( ) , 2500 ) ;
7095 }
7196}
7297
73- document . querySelectorAll ( 'fdd-container' ) . forEach ( c => new ExtensionFDD ( c ) ) ;
98+ // Bootstrap after parsing
99+ document . querySelectorAll ( 'fdd-container' ) . forEach ( c => {
100+ try {
101+ new ExtensionFDD ( c ) ;
102+ } catch ( e ) {
103+ console . error ( "OpenFDD Rendering Error:" , e ) ;
104+ }
105+ } ) ;
0 commit comments