Frage

I have been trying to change the order of elements in this code so the Account Information, Statistics and Website Traffic dividers (in that order) are listed before the jump-search divider.

The target page HTML looks like this (the page is a HostGator control panel):

<div id="sub">
<!-- Jump Search Start -->
    <div id="jump-search">
       <h3 style="margin:0">Find</h3>
    </div>
<!-- Jump Search End -->

<!-- Website Traffic Start -->
    <div class="minititle">Website Traffic</div>
       <div class="trafficcontain"></div>
       <div style="height:10px;"></div>
<!-- Website Traffic End -->

<!-- New Stats Start -->
    <div class="minititle truncate-table" id="statsnew">Statistics</div>
       <div id="statscontain"></div>
    <div style="height:10px;"></div>
<!-- New Stats End -->

<!-- Account Info Start -->
    <div class="minititle">Account Information</div>
       <div class="accntcontain"></div>
       <div style="height:10px;"></div>
<!-- Account Info End -->
</div>

After more than an hour fiddling with Greasemonkey I have nothing to show for it. Any help is much appreciated.

War es hilfreich?

Lösung

This is tricky because the sections are marked out by comments and not by any trustworthy HTML structure (except, maybe, the contents of the .minititle divs).
On the plus side, some of my host control panels have the same problem, so I already had something like the following script. ;)

We need to search for comment strings and then a way to get all the nodes in between matched comments. Alas, jQuery does not handle HTML comments well, But the straight DOM approach is not too difficult (Just might not work on all browsers. The following code was only tested on Firefox and Chrome.).

Here's a complete userscript that will work on a static page. You can also see the code in action at jsFiddle:

// ==UserScript==
// @name    Hostgator control panel, prioritize status panel order
// @match   https://*.hostgator.com/frontend/*
// @match   https://*.hostgator.com:2083/*
// @match   http://*.hostgator.com:2082/*
// @grant   GM_addStyle
// ==/UserScript==

//-- IMPORTANT!  Add your ports, in the match statements above, as needed.

var contNode    = document.querySelector ("#sub");
var insPoint    = findHtmlCommentsByRegex (contNode, /Jump Search Start/i);
if (insPoint && insPoint.length) {
  insPoint      = insPoint[0];

  moveCommentBoundedNodesBefore (insPoint, contNode, "Account Info");
  moveCommentBoundedNodesBefore (insPoint, contNode, "New Stats");
  moveCommentBoundedNodesBefore (insPoint, contNode, "Website Traffic");
}
else {
  reportError ('"Jump Search Start" comment not found!');
}

function moveCommentBoundedNodesBefore (targetNode, contNode, idingString) {
  var srchRegEx   = new RegExp (idingString + ' (?:Start|End)', 'i');
  var nodesToMove = getNodesBoundedByStartEndComments (contNode, srchRegEx);
  var pNode       = targetNode.parentNode;

  for (var J = 0, L = nodesToMove.length;  J < L;  ++J) {
    pNode.insertBefore (nodesToMove[J], targetNode);
  }
}

function getNodesBoundedByStartEndComments (contNode, srchRegex) {
  var boundedNodes  = [];
  var borders       = findHtmlCommentsByRegex (
    contNode, srchRegex, false //-- This MUST be false.
  );
  if (borders  &&  borders.length === 2) {
    var bNode       = borders[0];
    do {
      boundedNodes.push (bNode);
      if (bNode == borders[1]) {
        break;
      }
      bNode         = bNode.nextSibling;

    } while (bNode);
  }
  else {
    reportError ("Error finding comment pairs with: " + srchRegex);
    console.log ("borders: ", borders);
  }

  return boundedNodes;
}

function findHtmlCommentsByRegex (contNode, srchRegex, recurse) {
  var recurse       = recurse || false;
  var matchingComments  = [];

  if (contNode) {
    var chldNodes   = contNode.childNodes;

    for (var J = 0, L = chldNodes.length;  J < L;  ++J) {
      var cNode     = chldNodes[J];

      if (cNode.nodeType === Node.COMMENT_NODE) {
        if (srchRegex.test (cNode.nodeValue) ) {
          matchingComments.push (cNode);
        }
      }
      else if (recurse  &&  cNode.nodeType === Node.ELEMENT_NODE) {
        var subFind = findHtmlCommentsByRegex (cNode, srchRegex, recurse);
        if (subFind.length) {
          matchingComments.push (subFind);
        }
      }
    }
  }

  return matchingComments;
}

function reportError (mess) {
  //alert ("Problem found by GM script: " + mess);
  console.log ("Problem found by GM script: " + mess);
}



Warning:

Since you indicated that this was for a HostGator control panel, beware that on my HG panel, there is no <!-- New Stats Start --> comment -- an obvious error; all the other comment boundaries were correct, including for the plethora of junk and advertizing sections.

If this is the case for you as well, add this code:

var fubarDiv        = document.getElementById ("statsnew");
var fixitComment    = document.createComment ("New Stats Start");
fubarDiv.parentNode.insertBefore (fixitComment, fubarDiv);

just before the

moveCommentBoundedNodesBefore (insPoint, contNode, "New Stats");

line.
When I do that, the script works perfectly on my HostGator panel.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top