@@ -1133,35 +1133,82 @@ const _fallbacks = {
11331133 const overlay = document . createElement ( 'div' ) ;
11341134 overlay . id = 'gura-fallback-sheet' ;
11351135 overlay . style . cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:var(--overlay-color);backdrop-filter: blur(10px);z-index:99999;display:flex;justify-content:center;align-items:flex-end;' ;
1136+
11361137 const container = document . createElement ( 'div' ) ;
11371138 container . style . cssText = 'width:100%;max-width:800px;height:' + ( options . height || '60%' ) + ';max-height:calc(100% - 80px);background:var(--background-color);corner-shape: superellipse(1.5);border-radius:35px 35px 0 0;overflow:hidden;position:relative;border:1px solid var(--glass-border);box-shadow: var(--sun-shadow), 0 10px 30px rgba(0, 0, 0, 0.2);' ;
11381139
1140+ // Spinner Element
1141+ const spinnerContainer = document . createElement ( 'div' ) ;
1142+ spinnerContainer . className = 'sheet-loading-spinner' ;
1143+ spinnerContainer . style . cssText = 'position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); display: flex; justify-content: center; align-items: center; z-index: 1; transition: opacity 0.3s ease; pointer-events: none;' ;
1144+ spinnerContainer . innerHTML = `
1145+ <svg class="loading-spinner" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" style="width: 48px; height: 48px;">
1146+ <rect width="100%" height="100%" fill="currentColor" stroke="none" class="loading-spinner-ind" />
1147+ </svg>
1148+ ` ;
1149+ container . appendChild ( spinnerContainer ) ;
1150+
1151+ // Close Button
11391152 const closeBtn = document . createElement ( 'button' ) ;
11401153 closeBtn . textContent = 'Done' ;
11411154 closeBtn . style . cssText = 'position:absolute;top:10px;right:10px;z-index:10;padding:10px 15px;border-radius:50px;border:1px solid var(--glass-border);color:var(--text-color);background:var(--search-background);backdrop-filter:var(--edge-refraction-filter) saturate(2) blur(2.5px);cursor:pointer;' ;
11421155 closeBtn . onclick = ( ) => overlay . remove ( ) ;
1143-
1156+
1157+ // Iframe Element
11441158 const iframe = document . createElement ( 'iframe' ) ;
1145- iframe . style . cssText = 'width:100%;height:100%;border:none;corner-shape:inherit;border-radius:inherit;' ;
1159+ iframe . className = 'sheet-iframe' ;
1160+ iframe . setAttribute ( 'data-gurasuraisu-iframe' , 'true' ) ;
1161+ iframe . setAttribute ( 'data-is-sheet' , 'true' ) ;
1162+ if ( options . sourceAppId ) iframe . dataset . appId = options . sourceAppId ;
11461163
1164+ iframe . style . opacity = '0' ;
1165+ iframe . style . transition = 'opacity 0.3s ease' ;
1166+ iframe . onload = ( ) => {
1167+ iframe . style . opacity = '1' ;
1168+ spinnerContainer . style . opacity = '0' ;
1169+ setTimeout ( ( ) => {
1170+ if ( spinnerContainer . parentNode ) spinnerContainer . remove ( ) ;
1171+ } , 300 ) ;
1172+ } ;
1173+
1174+ // Setting iframe source
11471175 if ( options . url ) {
11481176 iframe . src = options . url ;
11491177 } else if ( options . html ) {
1150- iframe . srcdoc = options . html ;
1178+ iframe . sandbox = "allow-scripts" ; // Secure: No allow-same-origin
1179+
1180+ let headInjection = '' ;
1181+ if ( options . styleUrls && Array . isArray ( options . styleUrls ) ) {
1182+ options . styleUrls . forEach ( url => {
1183+ headInjection += `<link rel="stylesheet" href="${ url } ">\n` ;
1184+ } ) ;
1185+ }
1186+ if ( options . styles ) {
1187+ headInjection += `<style>\n${ options . styles } \n</style>\n` ;
1188+ }
1189+
1190+ const apiScriptUrl = new URL ( 'https://polygol.github.io/assets/gurapp/api/gurasuraisu-api.js' , window . location . origin ) . href ;
1191+ let htmlContent = options . html ;
1192+ if ( ! htmlContent . includes ( 'gurasuraisu-api.js' ) ) {
1193+ headInjection += `<script src="${ apiScriptUrl } "><\/script>\n` ;
1194+ }
1195+
1196+ if ( htmlContent . includes ( '<head>' ) ) {
1197+ htmlContent = htmlContent . replace ( '<head>' , '<head>\n' + headInjection ) ;
1198+ } else {
1199+ htmlContent = headInjection + htmlContent ;
1200+ }
1201+
1202+ iframe . srcdoc = htmlContent ;
11511203 }
1152-
1204+
1205+ // Append iframe and close button
11531206 container . appendChild ( closeBtn ) ;
11541207 container . appendChild ( iframe ) ;
1208+
1209+ // Append container to overlay
11551210 overlay . appendChild ( container ) ;
11561211 document . body . appendChild ( overlay ) ;
1157- } ,
1158- closeSheet : function ( ) {
1159- const sheet = document . getElementById ( 'gura-fallback-sheet' ) ;
1160- if ( sheet ) sheet . remove ( ) ;
1161- } ,
1162- // For functions that have no standalone equivalent, we can just log a warning.
1163- default : function ( functionName ) {
1164- console . warn ( `Gurasuraisu API: '${ functionName } ' is only available inside the Polygol environment.` ) ;
11651212 }
11661213} ;
11671214
0 commit comments