Repository: freeCodeCamp/freeCodeCamp
File: client/src/templates/Challenges/utils/frame.ts (TypeScript)

Code before:

export const scrollManager = new ScrollManager();

// we use two different frames to make them all essentially pure functions
// main iframe is responsible rendering the preview and is where we proxy the
export const mainPreviewId = 'fcc-main-frame';
// the test frame is responsible for running the assert tests
const testId = 'fcc-test-frame';
// the project preview frame demos the finished project
export const projectPreviewId = 'fcc-project-preview-frame';

const DOCUMENT_NOT_FOUND_ERROR = 'misc.document-notfound';

// base tag here will force relative links
// within iframe to point to '' instead of
// append to the current challenge url
// this also allows in-page anchors to work properly
// rather than load another instance of the learn

// window.onerror is added here to report any errors thrown during the building
// of the frame.  React dom errors already appear in the console, so onerror
// does not need to pass them on to the default error handler.

const createHeader = (id = mainPreviewId) => `
  <base href='' />
  <style>
    head *, title, meta, link, script {
      display: none !important;
    }
  </style>
  <script>
    window.__frameId = '${id}';
    window.onerror = function(msg) {
      const string = msg.toLowerCase();
      if (string.includes('script error')) {
        msg = 'Build error, open your browser console to learn more.';
      }
      console.log(msg);
      return true;
    };
    document.addEventListener('click', function(e) {
      let element = e.target;
      while(element && element.nodeName !== 'A') {
        element = element.parentElement;
      }
      if (element && element.nodeName === 'A' && new URL(element.href).hash === '') {
        e.preventDefault();
        window.parent.window.alert(
          i18nContent.t('misc.iframe-alert', { externalLink: element.href })
        )
      }

Review comment (bug):
```suggestion
  <style class="fcc-hide-header">
```
The CSSHelper class ignores `style` elements with classes, so this should fix those bugs. However, this is a bit of a hack, so let's wait until https://github.com/freeCodeCamp/freeCodeCamp/pull/56598 is in before we test this.

Assuming that this does the job, an explanatory comment (on line 87 or so) would help since it's far from obvious what this is doing.

Code after:

export const scrollManager = new ScrollManager();

// we use two different frames to make them all essentially pure functions
// main iframe is responsible rendering the preview and is where we proxy the
export const mainPreviewId = 'fcc-main-frame';
// the test frame is responsible for running the assert tests
export const testId = 'fcc-test-frame';
// the project preview frame demos the finished project
export const projectPreviewId = 'fcc-project-preview-frame';

const DOCUMENT_NOT_FOUND_ERROR = 'misc.document-notfound';

// base tag here will force relative links
// within iframe to point to '' instead of
// append to the current challenge url
// this also allows in-page anchors to work properly
// rather than load another instance of the learn

// window.onerror is added here to report any errors thrown during the building
// of the frame.  React dom errors already appear in the console, so onerror
// does not need to pass them on to the default error handler.

// The "fcc-hide-header" class on line 95 is added to ensure that the CSSHelper class ignores this style element
// during tests, preventing CSS-related test failures.

export const createHeader = (id = mainPreviewId) =>
  `
  <base href='' />
  <style class="fcc-hide-header">
    head *, title, meta, link, script {
      display: none !important;
    }
  </style>
  <script>
    window.__frameId = '${id}';
    window.onerror = function(msg) {
      const string = msg.toLowerCase();
      if (string.includes('script error')) {
        msg = 'Build error, open your browser console to learn more.';
      }
      console.log(msg);
      return true;
    };
    document.addEventListener('click', function(e) {
      let element = e.target;
      while(element && element.nodeName !== 'A') {
        element = element.parentElement;
      }
      if (element && element.nodeName === 'A' && new URL(element.href).hash === '') {
        e.preventDefault();