github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/cmd/deck/static/spyglass/spyglass.ts (about)

     1  import { isTransitMessage } from "./common";
     2  
     3  declare const src: string;
     4  declare const lensArtifacts: {[key: string]: string[]};
     5  declare const lenses: string[];
     6  
     7  // Loads views for this job
     8  function loadLenses(): void {
     9    for (let lens of lenses) {
    10      const frame = document.querySelector<HTMLIFrameElement>(`#iframe-${lens}`)!;
    11      frame.src = urlForLensRequest(lens, 'iframe');
    12    }
    13  }
    14  
    15  function queryForLens(lens: string): string {
    16    const data = {
    17      src,
    18      artifacts: lensArtifacts[lens],
    19    };
    20    return `req=${encodeURIComponent(JSON.stringify(data))}`;
    21  }
    22  
    23  function urlForLensRequest(lens: string, request: string): string {
    24    return `/spyglass/lens/${lens}/${request}?${queryForLens(lens)}`;
    25  }
    26  
    27  function frameForMessage(e: MessageEvent): HTMLIFrameElement {
    28    for (const frame of Array.from(document.querySelectorAll('iframe'))) {
    29      if (frame.contentWindow === e.source) {
    30        return frame;
    31      }
    32    }
    33    throw new Error("MessageEvent from unknown frame!?");
    34  }
    35  
    36  window.addEventListener('message', async (e) => {
    37    const data = e.data;
    38    if (isTransitMessage(data)) {
    39      const {id, message} = data;
    40      const frame = frameForMessage(e);
    41      const lens = frame.dataset.lens!;
    42  
    43      const respond = (response: string): void => {
    44        frame.contentWindow!.postMessage({id, message: {type: 'response', data: response}}, '*');
    45      };
    46  
    47      switch (message.type) {
    48        case "contentUpdated":
    49          frame.style.height = `${message.height}px`;
    50          frame.style.visibility = 'visible';
    51          document.querySelector<HTMLElement>(`#${lens}-loading`)!.style.display = 'none';
    52          respond('');
    53          break;
    54        case "request": {
    55          const req = await fetch(urlForLensRequest(lens, 'callback'),
    56            {body: message.data, method: 'POST'});
    57          respond(await req.text());
    58          break;
    59        }
    60        case "requestPage": {
    61          const req = await fetch(urlForLensRequest(lens, 'rerender'),
    62            {body: message.data, method: 'POST'});
    63          respond(await req.text());
    64          break;
    65        }
    66        case "updatePage": {
    67          const spinner = document.querySelector<HTMLElement>(`#${lens}-loading`)!;
    68          frame.style.visibility = 'visible';
    69          spinner.style.display = 'block';
    70          const req = await fetch(urlForLensRequest(lens, 'rerender'),
    71            {body: message.data, method: 'POST'});
    72          respond(await req.text());
    73          break;
    74        }
    75        default:
    76          console.warn(`Unrecognised message type "${message.type}" from lens "${lens}":`, data);
    77          break;
    78      }
    79    }
    80  });
    81  
    82  // We can't use DOMContentLoaded here or we end up with a bunch of flickering. This appears to be MDL's fault.
    83  window.addEventListener('load', () => {
    84      loadLenses();
    85  });