assets

package
v0.74.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 21, 2020 License: MIT Imports: 0 Imported by: 5

README

Asserts

helper.js

This lib is the helper that Rod will inject to each page to help quey, manipulate page contents.

Documentation

Index

Constants

View Source
const Helper = `() => {
` + `const rod={_(){},expose(){window.rod=rod},element(...e){const t=ensureScope(this);for(const n of e){const e=t.querySelector(n);if(e)return e}return null},elements(e){return ensureScope(this).querySelectorAll(e)},elementX(...e){const t=ensureScope(this);for(const n of e){const e=document.evaluate(n,t,null,XPathResult.FIRST_ORDERED_NODE_TYPE).singleNodeValue;if(e)return e}return null},elementsX(e){const t=ensureScope(this),n=document.evaluate(e,t,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE),r=[];let i;for(;i=n.iterateNext();)r.push(i);return r},elementR(...e){for(let t=0;t<e.length-1;t+=2){const n=e[t],r=e[t+1],i=new RegExp(r),o=Array.from((this.document||this).querySelectorAll(n)).find(e=>i.test(rod.text.call(e)));if(o)return o}return null},parents(e){let t=this.parentElement;const n=[];for(;t;)t.matches(e)&&n.push(t),t=t.parentElement;return n},containsElement(e){for(var t=e;null!=t;){if(t===this)return!0;t=t.parentElement}return!1},async initMouseTracer(e,t){if(await rod.waitLoad(),document.getElementById(e))return;const n=document.createElement("div");n.innerHTML=t;const r=n.lastChild;r.id=e,r.style="position: absolute; z-index: 2147483647; width: 17px; pointer-events: none;",r.removeAttribute("width"),r.removeAttribute("height"),document.body.appendChild(r)},updateMouseTracer(e,t,n){const r=document.getElementById(e);return!!r&&(r.style.left=t-2+"px",r.style.top=n-3+"px",!0)},rect(){const e=ensureElement(this).getBoundingClientRect();return{x:e.x,y:e.y,width:e.width,height:e.height}},async overlay(e,t,n,r,i,o){await rod.waitLoad();const s=document.createElement("div");if(s.id=e,s.style=` + "`" + `position: fixed; z-index:2147483647; border: 2px dashed red;\n        border-radius: 3px; box-shadow: #5f3232 0 0 3px; pointer-events: none;\n        box-sizing: border-box;\n        left: ${t}px;\n        top: ${n}px;\n        height: ${i}px;\n        width: ${r}px;` + "`" + `,r*i==0&&(s.style.border="none"),!o)return void document.body.appendChild(s);const d=document.createElement("div");d.style=` + "`" + `position: absolute; color: #cc26d6; font-size: 12px; background: #ffffffeb;\n        box-shadow: #333 0 0 3px; padding: 2px 5px; border-radius: 3px; white-space: nowrap;\n        top: ${i}px;` + "`" + `,d.innerHTML=o,s.appendChild(d),document.body.appendChild(s),window.innerHeight<d.offsetHeight+n+i&&(d.style.top=-d.offsetHeight-2+"px"),window.innerWidth<d.offsetWidth+t&&(d.style.left=window.innerWidth-d.offsetWidth-t+"px")},async elementOverlay(e,t){const n=ensureElement(this);let r=n.getBoundingClientRect();await rod.overlay(e,r.left,r.top,r.width,r.height,t);const i=()=>{const t=document.getElementById(e);if(null===t)return;const o=n.getBoundingClientRect();r.left!==o.left||r.top!==o.top||r.width!==o.width||r.height!==o.height?(t.style.left=o.left+"px",t.style.top=o.top+"px",t.style.width=o.width+"px",t.style.height=o.height+"px",r=o,setTimeout(i,100)):setTimeout(i,100)};setTimeout(i,100)},removeOverlay(e){const t=document.getElementById(e);t&&t.remove()},waitIdle:e=>new Promise(t=>{window.requestIdleCallback(t,{timeout:e})}),waitLoad(){const e=this===window;return new Promise((t,n)=>{if(e){if("complete"===document.readyState)return t();window.addEventListener("load",t)}else void 0===this.complete||this.complete?t():(this.addEventListener("load",t),this.addEventListener("error",n))})},inputEvent(){this.dispatchEvent(new Event("input",{bubbles:!0})),this.dispatchEvent(new Event("change",{bubbles:!0}))},selectText(e){const t=this.value.match(new RegExp(e));t&&this.setSelectionRange(t.index,t.index+t[0].length)},selectAllText(){this.select()},select(e,t,n){let r;switch(n){case"regex":r=e.map(e=>{const t=new RegExp(e);return e=>t.test(e.innerText)});break;case"css-selector":r=e.map(e=>t=>t.matches(e));break;default:r=e.map(e=>t=>t.innerText.includes(e))}const i=Array.from(this.options);r.forEach(e=>{const n=i.find(e);n&&(n.selected=t)}),this.dispatchEvent(new Event("input",{bubbles:!0})),this.dispatchEvent(new Event("change",{bubbles:!0}))},visible(){const e=ensureElement(this),t=e.getBoundingClientRect(),n=window.getComputedStyle(e);return"none"!==n.display&&"hidden"!==n.visibility&&!!(t.top||t.bottom||t.width||t.height)},invisible(){return!rod.visible.apply(this)},text(){switch(this.tagName){case"INPUT":case"TEXTAREA":return this.value;case"SELECT":return Array.from(this.selectedOptions).map(e=>e.innerText).join();case void 0:return this.textContent;default:return this.innerText}},resource(){return new Promise((e,t)=>{if(this.complete)return e(this.currentSrc);this.addEventListener("load",()=>e(this.currentSrc)),this.addEventListener("error",e=>t(e))})},addScriptTag(e,t,n){if(!document.getElementById(e))return new Promise((r,i)=>{var o=document.createElement("script");t?(o.src=t,o.onload=r):(o.type="text/javascript",o.text=n,r()),o.id=e,o.onerror=i,document.head.appendChild(o)})},addStyleTag(e,t,n){if(!document.getElementById(e))return new Promise((r,i)=>{var o;t?((o=document.createElement("link")).rel="stylesheet",o.href=t):((o=document.createElement("style")).type="text/css",o.appendChild(document.createTextNode(n)),r()),o.id=e,o.onload=r,o.onerror=i,document.head.appendChild(o)})},fetchAsDataURL:e=>fetch(e).then(e=>e.blob()).then(e=>new Promise((t,n)=>{var r=new FileReader;r.onload=(()=>t(r.result)),r.onerror=(()=>n(r.error)),r.readAsDataURL(e)}))};function ensureScope(e){return e===window?e.document:e}function ensureElement(e){return e.tagName?e:e.parentElement}
` + `
return rod }

//# sourceURL=__rod_helper__
`

Helper for rod

View Source
const Monitor = `<html>
  <head>
    <title>Rod Monitor - Pages</title>
    <style>
      body {
        margin: 0;
        background: #2d2c2f;
        color: white;
        padding: 20px;
        font-family: sans-serif;
      }
      a {
        color: white;
        padding: 1em;
        margin: 0.5em 0;
        font-size: 1em;
        text-decoration: none;
        display: block;
        border-radius: 0.3em;
        border: 1px solid transparent;
        background: #212225;
      }
      a:visited {
        color: #c3c3c3;
      }
      a:hover {
        background: #25272d;
        border-color: #8d8d96;
      }
    </style>
  </head>
  <body>
    <h3>Choose a Page to Monitor</h3>

    <div id="targets"></div>

    <script>
      async function update() {
        const list = await (await fetch('/api/pages')).json()
        let html = ''
        list.forEach((el) => {
          html += ` + "`" + `<a href='/page/${el.targetId}' title="${el.url}">${el.title}</a>` + "`" + `
        })

        window.targets.innerHTML = html

        setTimeout(update, 1000)
      }

      update()
    </script>
  </body>
</html>
`

Monitor for rod

View Source
const MonitorPage = `<html>
  <head>
    <style>
      body {
        margin: 0;
        background: #2d2c2f;
        color: #ffffff;
      }
      .navbar {
        font-family: sans-serif;
        border-bottom: 1px solid #1413158c;
        display: flex;
        flex-direction: row;
      }
      .error {
        color: #ff3f3f;
        background: #3e1f1f;
        border-bottom: 1px solid #1413158c;
        display: none;
        padding: 10px;
        margin: 0;
      }
      input {
        background: transparent;
        color: white;
        border: none;
        border: 1px solid #4f475a;
        border-radius: 3px;
        padding: 5px;
        margin: 5px;
      }
      .title {
        flex: 2;
      }
      .url {
        flex: 5;
      }
      .rate {
        flex: 1;
      }
    </style>
  </head>
  <body>
    <div class="navbar">
      <input
        type="text"
        class="title"
        title="title of the remote page"
        readonly
      />
      <input type="text" class="url" title="url of the remote page" readonly />
      <input
        type="number"
        class="rate"
        value="0.5"
        min="0"
        step="0.1"
        title="refresh rate (second)"
      />
    </div>
    <pre class="error"></pre>
    <img class="screen" />
  </body>
  <script>
    const id = location.pathname.split('/').slice(-1)[0]
    const elImg = document.querySelector('.screen')
    const elTitle = document.querySelector('.title')
    const elUrl = document.querySelector('.url')
    const elRate = document.querySelector('.rate')
    const elErr = document.querySelector('.error')

    document.title = ` + "`" + `Rod Monitor - ${id}` + "`" + `

    async function update() {
      const res = await fetch(` + "`" + `/api/page/${id}` + "`" + `)
      const info = await res.json()
      elTitle.value = info.title
      elUrl.value = info.url

      await new Promise((resolve, reject) => {
        const now = new Date()
        elImg.src = ` + "`" + `/screenshot/${id}?t=${now.getTime()}` + "`" + `
        elImg.style.maxWidth = innerWidth + 'px'
        elImg.onload = resolve
        elImg.onerror = () => reject(new Error('error loading screenshots'))
      })
    }

    async function mainLoop() {
      try {
        await update()
        elErr.attributeStyleMap.delete('display')
      } catch (err) {
        elErr.style.display = 'block'
        elErr.textContent = err + ''
      }

      setTimeout(mainLoop, parseFloat(elRate.value) * 1000)
    }

    mainLoop()
  </script>
</html>
`

MonitorPage for rod

View Source
const MousePointer = `` /* 1518-byte string literal not displayed */

MousePointer for rod

Variables

This section is empty.

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL