MediaWiki:Gadget-interactive.js

From Minecraft Discontinued Features Wiki
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/// <reference types="types-mediawiki" />

// eslint-disable-next-line no-undef
mw.hook('wikipage.content').add(() => {
  const calcs = document.querySelectorAll('div.tool')
  calcs.forEach((calc) => {
    const type = calc.getAttribute('data-type')
    if (!type) {
      console.error('No data-type attribute found on .tool', calc)
      return
    }

    const iframe = document.createElement('iframe')

    // a random string to use as id
    const id = Math.random().toString(36).substring(7)

    iframe.id = `tool-${id}`

    const attributes = calc.attributes
    for (let i = 0; i < attributes.length; i++) {
      iframe.setAttribute(attributes[i].name, attributes[i].value)
    }

    // eslint-disable-next-line no-undef
    const url = `/tools/${type}/#?id=${id}&locale=${mw.config.get('wgPageContentLanguage')}&url=${encodeURIComponent(window.location.href)}`

    if (localStorage.getItem('mcwCalcLocal') === 'true') {
      console.log('You are in development environment and tools are loaded from localhost.')
      iframe.src = `http://localhost:5173${url}`
    } else {
      iframe.src = `https://mcdf-static.github.io${url}`
    }

    // copy all children with .tool-parameter
    const parameters = calc.querySelectorAll('.tool-parameter')
    parameters.forEach((parameter) => {
      const iframeParameter = document.createElement('div')
      iframeParameter.className = 'tool-parameter'
      iframeParameter.innerHTML = parameter.innerHTML
      iframe.appendChild(iframeParameter)
    })

    calc.replaceWith(iframe)

    iframe.style.border = 'none'
    iframe.style.display = 'block'
    iframe.style.width = '100%'
    iframe.style.colorScheme = 'auto'

    const dataset = {}
    Object.entries(calc.dataset).forEach((entry) => {
      const key = entry[0]
      const value = entry[1]
      dataset[key] = value
    })

    iframe.addEventListener('load', () => {
      iframe.contentWindow.postMessage(
        {
          type: 'tool-theme-change',
          data: {
            theme: document.classList.contains('theme-light') ? 'light' : 'dark',
          },
        },
        new URL(iframe.src).origin
      )

      // eslint-disable-next-line no-undef
      mw.hook('ext.themes.themeChanged').add((theme) => { // for w.gg theme changer
        iframe.contentWindow.postMessage(
          {
            type: 'tool-theme-change',
            data: {
              theme,
            },
          },
          new URL(iframe.src).origin
        )
      })
    })

    window.addEventListener('message', (event) => {
      if (event.origin !== new URL(iframe.src).origin) return
      if (event.data.id !== id) return

      if (event.data.type === 'tool-init-request-data') {
        event.source.postMessage(
          {
            type: 'tool-init',
            data: {
              dataset,
              innerHTML: calc.innerHTML,
            },
          },
          new URL(iframe.src).origin
        )
      } else if (event.data.type === 'tool-height-change') {
        iframe.style.height = `${event.data.data.height}px`
      } else if (event.data.type === 'tool-clipboard') {
        navigator.clipboard.writeText(event.data.data.text)
      }
    })
  })
})