{"id":17,"date":"2026-02-23T10:36:56","date_gmt":"2026-02-23T10:36:56","guid":{"rendered":"https:\/\/wpnlighten.devvps.macrodesign.com\/?page_id=17"},"modified":"2026-02-23T10:38:28","modified_gmt":"2026-02-23T10:38:28","slug":"rack-space-configurator-embed","status":"publish","type":"page","link":"https:\/\/wpnlighten.devvps.macrodesign.com\/?page_id=17","title":{"rendered":"Rack Space Configurator Embed"},"content":{"rendered":"<div id=\"api-widget\" class=\"rackspace-widget-container\"><\/div><script>\r\nasync function loadWidget() {\r\n  try {\r\n    console.log('Attempting to fetch from API...');\r\n    \r\n    \/\/ Try a simple fetch without custom headers to avoid preflight\r\n    const testResponse = await fetch(\"https:\/\/standalone-rackspace-configurator.devvps.macrodesign.com\/colocation\/api\/headless\/headless.php?locations=BHM&countries=FR\");\r\n    \r\n    console.log('Response status:', testResponse.status);\r\n    console.log('Response ok:', testResponse.ok);\r\n    console.log('Response headers:');\r\n    for (let [key, value] of testResponse.headers.entries()) {\r\n      console.log(`  ${key}: ${value}`);\r\n    }\r\n    \r\n    if (!testResponse.ok) {\r\n      const errorText = await testResponse.text();\r\n      console.error('Error response body:', errorText);\r\n      throw new Error(`HTTP error! status: ${testResponse.status} - ${errorText}`);\r\n    }\r\n    \r\n    const html = await testResponse.text();\r\n    console.log('\ud83d\udcc4 Received HTML length:', html.length);\r\n    console.log('\ud83d\udcc4 HTML preview (first 500 chars):', html.substring(0, 500));\r\n    console.log('\ud83d\udcc4 Contains script tags:', html.includes('<script'));\r\n\r\n  const container = document.getElementById(\"api-widget\");\r\n  const shadow = container.attachShadow({ mode: \"open\" });\r\n\r\n  \/\/ Insert HTML\r\n  const template = document.createElement(\"template\");\r\n  template.innerHTML = html;\r\n  shadow.appendChild(template.content.cloneNode(true));\r\n\r\n\r\n\r\n  \/\/ Create a global reference to this shadow root for the widget to use\r\n  window.currentShadowRoot = shadow;\r\n\r\n  \/\/ Handle external scripts first\r\n  const externalScripts = Array.from(shadow.querySelectorAll(\"script[src]\"));\r\n  const inlineScripts = Array.from(shadow.querySelectorAll(\"script:not([src])\"));\r\n\r\n  console.log(`Found ${externalScripts.length} external scripts and ${inlineScripts.length} inline scripts`);\r\n  externalScripts.forEach((script, index) => {\r\n    console.log(`External script ${index + 1}: ${script.src}`);\r\n  });\r\n\r\n  \/\/ Load external scripts sequentially\r\n  for (const oldScript of externalScripts) {\r\n    await new Promise((resolve, reject) => {\r\n      const newScript = document.createElement(\"script\");\r\n      newScript.src = oldScript.src;\r\n      newScript.onload = () => {\r\n        console.log(`\u2705 Loaded external script: ${oldScript.src}`);\r\n        console.log(`   After loading, window.rackspace type: ${typeof window.rackspace}`);\r\n        console.log(`   Available window keys with 'rack':`, Object.keys(window).filter(k => k.toLowerCase().includes('rack')));\r\n        resolve();\r\n      };\r\n      newScript.onerror = (error) => {\r\n        console.error(`\u274c Failed to load external script: ${oldScript.src}`, error);\r\n        console.error(`   Error details:`, error);\r\n        resolve(); \/\/ Continue with other scripts even if one fails\r\n      };\r\n      console.log(`\u23f3 Starting to load: ${oldScript.src}`);\r\n      document.head.appendChild(newScript); \/\/ External scripts go to document head\r\n      oldScript.remove();\r\n    });\r\n  }\r\n\r\n  \/\/ Wait for the rackspace class to be available with polling\r\n  let rackspaceAvailable = false;\r\n  try {\r\n    await new Promise((resolve, reject) => {\r\n      let attempts = 0;\r\n      const maxAttempts = 50; \/\/ 5 seconds max (50 * 100ms)\r\n      \r\n      const checkRackspace = () => {\r\n        attempts++;\r\n        if (typeof window.rackspace === 'function') {\r\n          console.log(`\u2705 rackspace class is now available after ${attempts * 100}ms`);\r\n          rackspaceAvailable = true;\r\n          resolve();\r\n        } else if (attempts >= maxAttempts) {\r\n          console.error('\u274c Timeout: rackspace class never became available');\r\n          console.error('Available window properties containing \"rack\":', \r\n            Object.keys(window).filter(key => key.toLowerCase().includes('rack')));\r\n          console.error('All window properties (first 20):', Object.keys(window).slice(0, 20));\r\n          resolve(); \/\/ Don't reject, continue anyway\r\n        } else {\r\n          if (attempts % 10 === 0) { \/\/ Log every second\r\n            console.log(`\u23f3 Still waiting for rackspace class... Attempt ${attempts}, type:`, typeof window.rackspace);\r\n          }\r\n          setTimeout(checkRackspace, 100);\r\n        }\r\n      };\r\n      \/\/ Start checking immediately\r\n      checkRackspace();\r\n    });\r\n  } catch (error) {\r\n    console.error('Error in rackspace polling:', error);\r\n  }\r\n\r\n  \/\/ Execute inline scripts after rackspace is confirmed available\r\n  inlineScripts.forEach(oldScript => {\r\n    try {\r\n      \/\/ Create a new script element\r\n      const newScript = document.createElement(\"script\");\r\n      \r\n      \/\/ Wrap the inline script to provide shadow DOM context\r\n      const wrappedCode = `\r\n        (function() {\r\n          \/\/ Override document methods to work with shadow DOM\r\n          const originalGetElementById = document.getElementById;\r\n          const shadowRoot = window.currentShadowRoot;\r\n          \r\n          \/\/ Temporarily override getElementById to search in shadow DOM\r\n          document.getElementById = function(id) {\r\n            const shadowElement = shadowRoot ? shadowRoot.getElementById(id) : null;\r\n            return shadowElement || originalGetElementById.call(document, id);\r\n          };\r\n          \r\n          try {\r\n            \/\/ Debug: Check if rackspace class exists before running script\r\n            console.log('\ud83d\udd0d About to execute embedded script. Status check:', {\r\n              rackspace: typeof window.rackspace,\r\n              rackspaceAvailable: rackspaceAvailable,\r\n              currentShadowRoot: !!window.currentShadowRoot,\r\n              allWindowKeys: Object.keys(window).length\r\n            });\r\n            \r\n            if (!rackspaceAvailable && typeof window.rackspace !== 'function') {\r\n              console.warn('\u26a0\ufe0f Executing embedded script even though rackspace class is not available');\r\n            }\r\n            \r\n            ${oldScript.textContent}\r\n          } catch (scriptError) {\r\n            console.error('\u274c Error in embedded script execution:', scriptError);\r\n            console.error('Stack trace:', scriptError.stack);\r\n            console.error('Final rackspace check:', {\r\n              type: typeof window.rackspace,\r\n              exists: 'rackspace' in window,\r\n              constructor: window.rackspace?.constructor?.name\r\n            });\r\n          } finally {\r\n            \/\/ Restore original getElementById\r\n            document.getElementById = originalGetElementById;\r\n          }\r\n        })();\r\n      `;\r\n      \r\n      newScript.textContent = wrappedCode;\r\n      document.head.appendChild(newScript); \/\/ Execute in global context but with shadow DOM access\r\n      oldScript.remove();\r\n    } catch (error) {\r\n      console.error('Error executing inline script:', error);\r\n    }\r\n  });\r\n\r\n  \/\/ Clean up the global reference after a short delay\r\n  setTimeout(() => {\r\n    delete window.currentShadowRoot;\r\n  }, 1000);\r\n  \r\n  } catch (error) {\r\n    console.error('Error loading widget:', error);\r\n    const container = document.getElementById(\"api-widget\");\r\n    if (container) {\r\n      container.innerHTML = '<p>Error loading widget: ' + error.message + '<\/p>';\r\n    }\r\n  }\r\n}\r\n\r\nloadWidget();\r\n<\/script>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-17","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/wpnlighten.devvps.macrodesign.com\/index.php?rest_route=\/wp\/v2\/pages\/17","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wpnlighten.devvps.macrodesign.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/wpnlighten.devvps.macrodesign.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/wpnlighten.devvps.macrodesign.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wpnlighten.devvps.macrodesign.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=17"}],"version-history":[{"count":2,"href":"https:\/\/wpnlighten.devvps.macrodesign.com\/index.php?rest_route=\/wp\/v2\/pages\/17\/revisions"}],"predecessor-version":[{"id":19,"href":"https:\/\/wpnlighten.devvps.macrodesign.com\/index.php?rest_route=\/wp\/v2\/pages\/17\/revisions\/19"}],"wp:attachment":[{"href":"https:\/\/wpnlighten.devvps.macrodesign.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=17"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}