HTML Sniffer

A tool to sniff HTML tags and attributes.

Version vom 20.01.2016. Aktuellste Version

Du musst eine Erweiterung wie Tampermonkey, Greasemonkey oder Violentmonkey installieren, um dieses Skript zu installieren.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

Sie müssten eine Skript Manager Erweiterung installieren damit sie dieses Skript installieren können

(Ich habe schon ein Skript Manager, Lass mich es installieren!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name HTML Sniffer
// @namespace http://gerald.top
// @author Gerald <[email protected]>
// @icon	http://cn.gravatar.com/avatar/a0ad718d86d21262ccd6ff271ece08a3?s=80
// @version 0.1.1
// @description A tool to sniff HTML tags and attributes.
// @include *
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==

function prevent(e) {
  e.preventDefault();
}

function capture(e) {
  prevent(e);
  if (sniffer.current) {
    sniffer.current.classList.remove(sniffer.CURRENT);
  }
  sniffer.current = e.target;
  sniffer.current.classList.add(sniffer.CURRENT);
  updateDOM();
}

function onmouseover(e) {
  if (sniffer.hovered) {
    sniffer.hovered.classList.remove(sniffer.HOVERED);
  }
  sniffer.hovered = e.target;
  sniffer.hovered.classList.add(sniffer.HOVERED);
}

function safeHTML(html) {
  return html.replace(/[<&]/g, (m) => {
    return {
      '<' : '&lt;',
      '&' : '&amp;',
    }[m];
  });
}

function updateDOM() {
  var current = sniffer.current;
  var tagName = current.tagName.toLowerCase();
  var tags = document.querySelectorAll(tagName);
  var arrayProto = Array.prototype;
  var index = arrayProto.indexOf.call(tags, current);
  dom.domName.textContent = tagName;
  dom.domRank.textContent = `${index} of ${tags.length}`;
  dom.domAttrs.innerHTML = arrayProto.map.call(current.attributes, (attr) => {
    return `
    <li>
      <span class="dom-attr-key">${safeHTML(attr.name)}</span>
      =
      <span class="dom-attr-val">${safeHTML(attr.value)}</span>
    </li>
    `;
  }).join('');
}

function init() {
  initFrame();
  document.addEventListener('mousedown', capture, true);
  document.addEventListener('click', prevent, true);
  document.addEventListener('mouseover', onmouseover, false);
  locate(GM_getValue('hs-location'));
}

function locate(pos) {
  pos = pos || {};
  if (pos.left == null) pos.left = 'auto';
  else if (!isNaN(pos.left)) pos.left += 'px';
  if (pos.right == null) {
    pos.right = pos.left == 'auto' ? 0 : 'auto';
  } else if (!isNaN(pos.right)) pos.right += 'px';
  if (pos.bottom == null) pos.bottom = 'auto';
  else if (!isNaN(pos.bottom)) pos.bottom += 'px';
  if (pos.top == null) {
    pos.top = pos.bottom == 'auto' ? 0 : 'auto';
  } else if (!isNaN(pos.top)) pos.top += 'px';
  var frame = dom.frame;
  frame.style.top = pos.top;
  frame.style.left = pos.left;
  frame.style.right = pos.right;
  frame.style.bottom = pos.bottom;
}

function initFrame() {
  var frame = dom.frame = document.createElement('iframe');
  frame.id='hsniffer';
  document.body.appendChild(frame);
  var doc = frame.contentDocument;
  var style = doc.createElement('style');
  style.innerHTML = `
    body {
      min-height: 100%;
      padding: 1em;
      background: wheat;
      cursor: move;
    }
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    .dom {
      cursor: text;
    }
    ul {
      padding: 20px;
    }
    .dom-attr-key {
      color: dodgerblue;
    }
    .dom-attr-val {
      color: green;
    }
  `;
  doc.head.appendChild(style);
  doc.body.innerHTML = `
  <h1>HTML Sniffer</h1>
  <div class="dom">
  Current DOM: <span class="dom-name"></span>
  <br>
  Rank: <span class="dom-rank"></span>
  <br><ul class="dom-attrs"></ul>
  </div>
  `;
  dom.dom = doc.body.querySelector('.dom');
  dom.domName = doc.body.querySelector('.dom-name');
  dom.domRank = doc.body.querySelector('.dom-rank');
  dom.domAttrs = doc.body.querySelector('.dom-attrs');
  doc.addEventListener('mousedown', onMoveStart, false);

  var moving;
  function onMoveStart(e) {
    if (dom.dom.contains(e.target)) return;
    e.preventDefault();
    if (moving) return;
    moving = {
      x: e.clientX,
      y: e.clientY,
    };
    doc.addEventListener('mousemove', onMoving, false);
    doc.addEventListener('mouseup', onMoveEnd, false);
  }
  function onMoving(e) {
    var rect = frame.getBoundingClientRect();
    locate({
      left: rect.left + e.clientX - moving.x,
      top: rect.top + e.clientY - moving.y,
    });
  }
  function onMoveEnd(e) {
    var rect = frame.getBoundingClientRect();
    var pos = {};
    var right = document.body.clientWidth - rect.right;
    if (rect.left > right) pos.right = right;
    else pos.left = rect.left;
    var bottom = document.body.clientHeight - rect.bottom;
    if (rect.top > bottom) pos.bottom = bottom;
    else pos.top = rect.top;
    locate(pos);
    GM_setValue('hs-location', pos);
    moving = null;
    doc.removeEventListener('mousemove', onMoving, false);
    doc.removeEventListener('mouseup', onMoveEnd, false);
  }
}

GM_addStyle(`
  #hsniffer {
    position: fixed;
    width: 300px;
    height: 300px;
    border: 2px ridge gray;
    z-index: 10000;
  }
  *:not(#hsniffer).hsniffer-highlight {
    background: rgba(0,128,255,.3) !important;
    outline: 2px solid orange !important;
  }
  .hsniffer-current {
    background: rgba(0,128,255,.5) !important;
    outline: 2px solid red !important;
  }
`);
var dom = {};
var sniffer = {
  HOVERED: 'hsniffer-highlight',
  CURRENT: 'hsniffer-current',
};
init();