Online IDE Support JS

Injects elements into a codepen IDE for demonstration purposes

目前为 2022-01-10 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/438329/1007303/Online%20IDE%20Support%20JS.js

// BEGIN SUPPORTING CODE
let delay = 0;
let combinedSteps = `unset`;
let pen = {
  nav: undefined,
  cmd: undefined,
  log: undefined,
  hide: ()=> {
    pen.nav && (pen.nav.classList.add(`penHidden`));
    pen.cmd && (pen.cmd.classList.add(`penHidden`));
    pen.log && (pen.log.classList.add(`penHidden`));
  },
};
const cmdInfo = {
  id: `instructions`,
}
const logInfo = {
  id: `logText`,
  class: `logContainer`
}
const navInfo = {
  id: `penNav`,
  class: `penNavigation`,
}

const action = (msgcmd, combine) => {
  const penHeader = document.getElementById(cmdInfo.id);
  const stime = 3000;
  combine = combine === `combine` ? true : false;

  if (combine) {
    combinedSteps !== true && (delay += stime);
    combinedSteps = true;
  } else if(combinedSteps == `unset`) {
    delay += stime;
  } else if(combinedSteps === true) {
    delay += stime/4;
    combinedSteps = false;
  }
  setTimeout(()=> {
    if (typeof msgcmd === `string`) {
      penHeader.classList.add(`pulse`);
      penHeader.innerHTML = msgcmd;
      setTimeout(() => {penHeader.classList.remove(`pulse`)}, 1000)
    } else {
      msgcmd();
    }
  }, delay);
};

const consoleLog = (msg) => {
  const logEl = document.getElementById(logInfo.id);
  logEl.value = `${msg}\n${logEl.value}`
};

const createElement = (nodeType, props) => {
  const domNode = document.createElement(nodeType);
  if (props && "object" === typeof props) {
    for (const prop in props) {
      if (prop === "html") {
        domNode.innerHTML = props[prop];
      } else if (prop === "text") {
        domNode.textContent = props[prop];
      } else {
        if (prop.slice(0, 5) === "aria_" || prop.slice(0, 4) === "data_") {
          const attr = prop.slice(0, 4) + "-" + prop.slice(5);
          domNode.setAttribute(attr, props[prop]);
        } else {
          domNode.setAttribute(prop, props[prop]);
        }
      }
      // Set attributes on the element if passed
      if (["role", "aria-label"].includes(prop)) domNode.setAttribute(prop, props[prop]);
    }
  }
  return domNode;
};

const initialize = () => {
  // Add UI elements if not provided
  if (!document.getElementById(logInfo.id)) {
    addStyle(`
    .pulse {
        animation: pulse 1s 1;
      }

      @keyframes pulse {
        0% {
          background-color: #001F3F;
        }
        100% {
          background-color: #FFFFFF;
        }
      }

      .logClosed {
        left: -90%;
      }
      .logContainer {
        position: absolute;
        z-index: 9999;
        width: 80%;
        margin-left: 10%;
      }
      .logContainerLabel {
        background: black;
        color: white;
        position: relative;
        float: right;
        top: 44px;
        left: 47px;
        max-width: 6rem;
        text-align: right;
        padding: 0.1rem 0.265rem;
        transform: rotate(-90deg);
        cursor: pointer;
      }
      #logText {
        width:100%;
        height:20rem;
        color:white;
        background:black;
        font-size: 0.7rem;
        font-family: monospace;
        line-height: 0.9rem;
      }

      .penNavigation {
        background: aliceblue;
        min-height: 3rem;
        margin-bottom: 0.625rem;
        padding: 0.625rem;
        z-index: 9999;
        position: relative;

        .dds__button--sm {
          margin-right: 0.25rem;
        }
      }

      .penHidden {
        display: none;
      }
    `)
    const logEl = createElement(`div`, {
      class: `${logInfo.class} logClosed`,
    });
    const logLabel = createElement(`div`, {
      id: `${logInfo.id}Label`,
      class: `${logInfo.class}Label`,
      text: `console`
    });
    logEl.appendChild(logLabel);
    const textEl = createElement(`textarea`, {
      id: logInfo.id,
    });
    logEl.appendChild(textEl);
    document.querySelector(`body`).prepend(logEl);
    
    logLabel.addEventListener(`click`, (e) => {
      logEl.classList.toggle('logClosed');
    })
  }

  if (!document.getElementById(cmdInfo.id)) {
    const instrEl = createElement(`h5`, {
      id: cmdInfo.id,
      text: ``,
    });
    document.querySelector(`body`).prepend(instrEl);
  }

  if (!document.getElementById(navInfo.id)) {
    const navEl = createElement(`div`, {
      class: navInfo.class,
      id: navInfo.id,
    });
    document.querySelector(`body`).prepend(navEl);
  }

  pen.nav = document.getElementById(navInfo.id);
  pen.cmd = document.getElementById(cmdInfo.id);
  pen.log = document.getElementById(logInfo.id);
};

const addPenButton = (lText, lAction) => {
  if (typeof lText === `string`) {
    const newButton = createElement(`button`, {
      class: `dds__button dds__button--sm`,
      text: lText
    });
    newButton.addEventListener(`click`, (e) => {
      lAction();
    });
    pen.nav.appendChild(newButton);
  } else { // presume we are moving an existing element to the pen nav
    pen.nav.appendChild(lText);
  }
};

const addStyle = (styles) => {
  /* Create style document */
  var css = document.createElement('style');
  css.type = 'text/css';

  if (css.styleSheet)
    css.styleSheet.cssText = styles;
  else
    css.appendChild(document.createTextNode(styles));

  /* Append style to the tag name */
  document.getElementsByTagName("head")[0].appendChild(css);
}


const runDemo = (demo) => {
  consoleLog(`\n${demo.selector} has the following events: ${demo.events}`);

  demo.events.forEach((ev)=>{
    document.addEventListener(ev, (e)=> {
      consoleLog(ev, e);
    })
  })

  let hasDispose = false;
  Object.keys(demo.component).forEach(key=>{
    if (typeof demo.component[key] === `function`) {
      if (key !== `dispose`) {
        addPenButton(key, demo.component[key]);
      } else {
        hasDispose = true;
      }
    } else {
      consoleLog(`
${demo.selector} has the property:
.${key} = ${demo.component[key]}
(open console to see more details)`);
      console.log(demo.component[key]);
    }
  })

  hasDispose && (addPenButton(`dispose`, ()=>{
    demo.component[`dispose`]();
    pen.nav.querySelectorAll(`button`).forEach(b=>b.disabled = `true`);
  }));
};

initialize();

// END SUPPORTING CODE

/*
  pen.hide();
*/
/*
runDemo({
  selector: `more-less`,
  events: [`ddsMoreLessExpandEvent`, `ddsMoreLessCollapseEvent`],
  component: {
    property1: `soidjsoaidjo`,
    method1: ()=>{}
  },
});
*/