Permalink
Browse files

drastically improved SPAN algorithm so that it minimizes the number o…

…f spans in hierarchical DOM elements
  • Loading branch information...
1 parent a84e408 commit 7a52b4cf7700350a166f29bea2f0b0781a22806a @slifty committed Jul 28, 2011
Showing with 107 additions and 70 deletions.
  1. +95 −61 critical.min.js
  2. +4 −4 datarake.php
  3. +3 −1 index.php
  4. +5 −4 styles/critical.min.css
View
@@ -24,78 +24,112 @@
if(data.verdicts.length > 0) {
for(var x = 0; x < data.verdicts.length; ++x) {
var verdict = data.verdicts[x];
- var range = document.createRange();
var p = paragraphs[data.pid];
- var startNode = p;
- var endNode = p;
- var startOffset = 0;
- var endOffset = 0;
- if(range) {
- // Loop through the child nodes
- var children = Array.prototype.slice.call(p.childNodes);
- var cursor = 0;
+
+ // Recursive method to minimize the number of spans inserted
+ var verdictStart = verdict.contentStart;
+ var verdictEnd = verdict.contentStart + verdict.contentLength;
+
+ (function createSPAN(object, cursor) {
+ if(object.childNodes.length == 0)
+ return object.length;
+
+ // Loop through each child to find the beginning and end
+ var children = Array.prototype.slice.call(object.childNodes);
+ var familyLength = 0;
+
+ var startIndex = -1;
+ var endIndex = -1;
+ var startOffset = 0;
+ var endOffset = 0;
+ var endNodeLength = 0;
for(var y = 0; y < children.length ; ++y) {
var child = children[y];
- // If child is a parent, fold in deeper object
- if(child.childNodes.length > 0) {
- children = children.slice(0,y).concat(Array.prototype.slice.call(child.childNodes)).concat(children.slice(y+1));
- --y;
- continue;
- }
+ var childLength = createSPAN(child, cursor);
+ var childStart = cursor;
+ var childEnd = childStart + childLength;
+ cursor += childLength;
+ familyLength += childLength;
- // Is the first content character in this child
- if((cursor <= verdict.contentStart)
- && (cursor + child.length >= verdict.contentStart)) {
- startNode = child;
- startOffset = verdict.contentStart - cursor;
- }
+ if(verdictEnd < childStart) continue; // We're past the end of the verdict
+ if(verdictStart >= childEnd) continue; // We haven't hit the start of the verdict
- // Is the last content character in this child
- if(cursor + child.length > verdict.contentStart + verdict.contentLength) {
- endNode = child;
- endOffset = verdict.contentStart + verdict.contentLength - cursor;
- break;
+ if(verdictEnd >= childStart) {
+ endIndex = y;
+ endOffset = Math.min(childLength, verdictEnd - childStart);
+ endNodeLength = childLength;
+ }
+
+ if(startIndex == -1) {
+ startOffset = Math.max(0,verdictStart - childStart);
+ startIndex = y;
}
- cursor += child.length
}
- range.setStart(startNode, startOffset);
- range.setEnd(endNode, endOffset);
+
+ // Case 0: The verdict doesn't appear at all in this family
+ if(startIndex == -1)
+ return familyLength;
+
+ // Case 1: This entire node is incuded in the verdict
+ if(startIndex == 0 && startOffset == 0 && (endIndex == -1 || (endIndex == children.length-1 && endOffset == endNodeLength)))
+ return familyLength;
+
+ // Case 2: At least one endpoint is in this family
+ var range = document.createRange();
+
+ // Set the start
+ if(startOffset == 0)
+ range.setStartBefore(children[startIndex])
+ else if(children[startIndex].childNodes.length == 0)
+ range.setStart(children[startIndex], startOffset);
+ else if(startIndex + 1 < children.length)
+ range.setStartBefore(children[startIndex + 1]);
+
+ // Set the end
+ if(endIndex == -1) // The verdict end isn't in this family
+ range.setEndAfter(children[children.length - 1]);
+ else if(children[endIndex].childNodes.length == 0)
+ range.setEnd(children[endIndex], endOffset);
+ else if(endOffset = endNodeLength)
+ range.setEndBefore(children[endIndex]);
+
var s = document.createElement("span");
s.className = "critical " + verdict.verdictClass;
range.surroundContents(s);
- // range.setStart(p, 1);
- // range.setEnd(p, 2);
- // range.surroundContents(document.createElement("span"));
- } else if (document.selection) {
- // Internet Explorer
- mainRange = document.selection.createRange();
- tempRange = document.selection.createRange();
- tempRange.collapse(true);
- var selectedElement = tempRange.parentElement();
- var contentID = $(selectedElement).attr("id").slice(STCONST_PLAYER_TRANSCRIPTCONTENT_PREFIX.length);
- var selectedContent = transcript.getContentByID(contentID);
- var transcriptID = transcript.transcriptID;
-
- var quoteLinkURL = STgetQuoteLinkURL(transcriptID, selectedContent.timestamp);
-
- var container = document.createElement("div");
- $(container).css("visibility","hidden");
-
- var frontText = "<a href='" + quoteLinkURL + "'>";
- var backText = "</a>";
- var h = frontText + mainRange.htmlText + backText;
- $(container).html(h);
- $(document.body).append(container);
-
- var newRange = document.body.createTextRange()
- newRange.moveToElementText(container);
- newRange.select();
- window.setTimeout(function () {
- mainRange.select();
- $(container).remove();
- }, 0)
- }
+
+ return familyLength;
+ })(p,0);
+
+ // else if (document.selection) {
+ // // Internet Explorer
+ // mainRange = document.selection.createRange();
+ // tempRange = document.selection.createRange();
+ // tempRange.collapse(true);
+ // var selectedElement = tempRange.parentElement();
+ // var contentID = $(selectedElement).attr("id").slice(STCONST_PLAYER_TRANSCRIPTCONTENT_PREFIX.length);
+ // var selectedContent = transcript.getContentByID(contentID);
+ // var transcriptID = transcript.transcriptID;
+ //
+ // var quoteLinkURL = STgetQuoteLinkURL(transcriptID, selectedContent.timestamp);
+ //
+ // var container = document.createElement("div");
+ // $(container).css("visibility","hidden");
+ //
+ // var frontText = "<a href='" + quoteLinkURL + "'>";
+ // var backText = "</a>";
+ // var h = frontText + mainRange.htmlText + backText;
+ // $(container).html(h);
+ // $(document.body).append(container);
+ //
+ // var newRange = document.body.createTextRange()
+ // newRange.moveToElementText(container);
+ // newRange.select();
+ // window.setTimeout(function () {
+ // mainRange.select();
+ // $(container).remove();
+ // }, 0)
+ // }
}
}
}
View
@@ -45,9 +45,9 @@
$claim1->setContent("The U.S. government calculates inflation without adding in the price of food and energy");
$claim1->save();
-$claim1 = new Claim();
-$claim1->setContent("Social Security recipients are not receiving a cost-of-living adjustment because the government");
-$claim1->save();
+$claim2 = new Claim();
+$claim2->setContent("Social Security recipients are not receiving a cost-of-living adjustment because the government");
+$claim2->save();
// Add in some temporary snippets
@@ -66,7 +66,7 @@
$verdict1->save();
$verdict1 = new Verdict();
-$verdict1->setClaimID($claim1->getItemID());
+$verdict1->setClaimID($claim2->getItemID());
$verdict1->setResultClassID($RC_true->getItemID());
$verdict1->save();
View
@@ -13,7 +13,7 @@
<div id="main">
<p><a href="javascript:var%20criticalDomain='http://<?PHP echo($SITE_DOMAIN.$SITE_ROOT); ?>';var%20s=document.createElement('script');s.type='text/javascript';document.body.appendChild(s);s.src=criticalDomain+'/critical.min.js';void(0);">Apply Truth Goggles</a> <-- Drag this to your toolbar!</p>
<br />
- <p>While advising his Fox News viewers to talk about inflation at their Thanksgiving dinners, Glenn Beck falsely claimed that the government removed food and energy prices from <b>its measure <i>of</i> inflation</b> to hide rising prices, that a survey showed economists are “worried” about inflation, and that Social Security recipients are not receiving a cost-of-living adjustment because the government “changed the calculation.”</p>
+ <p><b>While</b> advising his Fox News viewers to talk about inflation at their Thanksgiving dinners, Glenn Beck falsely claimed that the government removed food and energy prices from <b>its measure <i>of</i> inflation to hide rising prices, that a survey showed economists are “worried”</b> about inflation, and that Social Security recipients are not receiving a cost-of-living adjustment because the government “changed the calculation.”</p>
<br />
<p>
<span class="critical false">False statements appear red.</span><br /><br />
@@ -23,11 +23,13 @@
</p>
<p>It also works elsewhere on the internet! Check out any of these articles:</p>
+ <br />
<ul>
<li><a href="http://kaystreet.wordpress.com/2010/11/27" target="_blank">Example 1</a></li>
<li><a href="http://mediamatters.org/mobile/research/201011230057" target="_blank">Example 2</a></li>
<li><a href="http://www.commynews.com/tag/dinner" target="_blank">Example 3</a></li>
</ul>
+ <br />
<p>and try running the bookmarklet again.</p>
</div>
<div id="footer"></div>
View
@@ -1,4 +1,5 @@
-.critical.true {background: #99FF99}
-.critical.mostlyTrue {background: #99FFFF}
-.critical.mostlyFalse {background: #FFFF99}
-.critical.false {background: #FF9999}
+.critical {overflow: visible; color: #000000;}
+.critical.true {background: #99FF99;}
+.critical.mostlyTrue {background: #99FFFF;}
+.critical.mostlyFalse {background: #FFFF99;}
+.critical.false {background: #FF9999;}

0 comments on commit 7a52b4c

Please sign in to comment.