Skip to content

Commit

Permalink
Added highlighter module, ported from old 1.2 branch
Browse files Browse the repository at this point in the history
  • Loading branch information
timdown committed Sep 11, 2011
1 parent 9391479 commit f664afe
Show file tree
Hide file tree
Showing 8 changed files with 551 additions and 73 deletions.
174 changes: 174 additions & 0 deletions demos/highlighter.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Rangy Highlighter Module Demo</title>
<link href="demo.css" rel="stylesheet" type="text/css">
<style type="text/css">
.highlight {
background-color: yellow;
}

.note {
background-color: limegreen;
}
</style>
<script type="text/javascript" src="../lib/log4javascript.js"></script>
<script type="text/javascript" src="../src/js/core/core.js"></script>
<script type="text/javascript" src="../src/js/core/dom.js"></script>
<script type="text/javascript" src="../src/js/core/domrange.js"></script>
<script type="text/javascript" src="../src/js/core/wrappedrange.js"></script>
<script type="text/javascript" src="../src/js/core/wrappedselection.js"></script>
<script type="text/javascript" src="../src/js/modules/rangy-serializer.js"></script>
<script type="text/javascript" src="../src/js/modules/rangy-cssclassapplier.js"></script>
<script type="text/javascript" src="../src/js/modules/rangy-selectionsaverestore.js"></script>
<script type="text/javascript" src="../src/js/modules/rangy-highlighter.js"></script>
<script type="text/javascript">
var serializedHighlights = decodeURIComponent(window.location.search.slice(window.location.search.indexOf("=") + 1));
var highlighter;

var initialDoc;

window.onload = function() {
rangy.init();

highlighter = rangy.createHighlighter();

highlighter.addCssClassApplier(rangy.createCssClassApplier("highlight", {
ignoreWhiteSpace: true,
tagNames: ["span", "a"]
}));

highlighter.addCssClassApplier(rangy.createCssClassApplier("note", {
ignoreWhiteSpace: true,
elementTagName: "a",
elementProperties: {
href: "#",
onclick: function() {
var highlight = highlighter.getHighlightForElement(this);
if (window.confirm("Delete this note (ID " + highlight.id + ")?")) {
highlighter.removeHighlights( [highlight] );
}
return false;
}
}
}));


if (serializedHighlights) {
//alert("Restoring serializedHighlights " + serializedHighlights);
highlighter.deserialize(serializedHighlights);
}
};


function highlightSelectedText() {
var newHighlights = highlighter.highlightSelection("highlight");
//alert("Created " + newHighlights.length + " highlights");
}

function noteSelectedText() {
var newHighlights = highlighter.highlightSelection("note");
//alert("Created " + newHighlights.length + " notes");
}

function removeHighlightFromSelectedText() {
highlighter.unhighlightSelection();
}

function reloadPage(button) {
button.form.elements['serializedHighlights'].value = highlighter.serialize();
button.form.submit();
}

</script>
</head>
<body>
<div id="buttons">
<h3>Highlighter</h3>
<p>Make a selection in the document and use the buttons below to highlight and unhighlight.</p>

<!--
<h3>Serialize selection</h3>
Click the button to serialize the selection. The serialized selection will appear in the text box.
<input type="text" disabled id="serializedSelection" size="30">
<input type="button" disabled id="serializeButton" value="Serialize selection" unselectable="on" class="unselectable">
<h3>Deserialize selection</h3>
Paste a serialized selection into the text box below and click the button to restore the serialized selection.
<input type="text" disabled id="selectionToDeserialize" size="30">
<input type="button" disabled id="deserializeButton" value="Restore selection" unselectable="on" class="unselectable">
<h3>Preserving the selection between page requests</h3>
The selection on this page will be preserved between page requests. Press the following button or your browser's
refresh button to refresh the page
<br>
-->

<input type="button" onclick="highlightSelectedText();" value="Highlight selection">
<input type="button" onclick="noteSelectedText();" value="Add note to selection">
<input type="button" onclick="removeHighlightFromSelectedText();" value="Remove highlights from selection">
<input type="button" onclick="highlighter.deserialize(highlighter.serialize())" value="Serialize and deserialize">

<h3>Preserving the selection between page requests</h3>
<form action="highlighter.html" method="get">
Highlights can be preserved between page requests. Press the following button to reload the page with the
highlights preserved:
<br>
<input type="hidden" name="serializedHighlights" value="">
<input type="button" value="Reload" onclick="reloadPage(this)">
</form>
</div>

<div id="content">
<h1>Rangy Serializer Module Demo</h1>

<!-- A comment -->

<p id="intro">
Please use your mouse and/or keyboard to make selections from the sample content below and use the buttons on
the left hand size to serialize and deserialize the selection. Also, the selection will be preserved when you
refresh the page.
</p>

<p>
<b>Association football</b> is a sport played between two teams. It is usually called <b>football</b>, but in
some countries, such as the United States, it is called <b>soccer</b>. In
<a href="http://simple.wikipedia.org/wiki/Japan">Japan</a>, New Zealand, South Africa, Australia, Canada and
Republic of Ireland, both words are commonly used.
</p>
<p>
Each team has 11 players on the field. One of these players is the <i>goalkeeper</i>, and the other ten are
known as <i>"outfield players."</i> The game is played by <b>kicking a ball into the opponent's goal</b>. A
match has 90 minutes of play, with a break of 15 minutes in the middle. The break in the middle is called
half-time.
</p>
<h2>Competitions <span class="smaller">(this section is editable)</span></h2>
<p contenteditable="true">
There are many competitions for football, for both football clubs and countries. Football clubs usually play
other teams in their own country, with a few exceptions. <b>Cardiff City F.C.</b> from Wales for example, play
in the English leagues and in the English FA Cup.
</p>
<h2>Who plays football <span class="smaller">(this section is editable and in pre-formatted text)</span></h2>
<pre contenteditable="true">
Football is the world's most popular sport. It is played in more
countries than any other game. In fact, FIFA (the Federation
Internationale de Football Association) has more members than the
United Nations.

It is played by both males and females.


</pre>
<p id="controlRange" style="display: none" contenteditable="true">
Some controls to put in a ControlRange: <input> and <input> and <input>
</p>
</div>

<p class="small">
Text adapted from <a href="http://simple.wikipedia.org/wiki/Association_football">Simple Wikipedia page on
Association Football</a>, licensed under the
<a href="http://simple.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License">Creative
Commons Attribution/Share-Alike License</a>.
</p>
</body>
</html>
1 change: 1 addition & 0 deletions demos/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ <h1>Rangy demos</h1>
<li><a href="cssclassapplier.html">CSS class applier module</a></li>
<li><a href="position.html">Position module (work in progress)</a></li>
<li><a href="commands.html">Commands module (work in progress)</a></li>
<li><a href="highlighter.html">Highlighter module (work in progress)</a></li>
<li><a href="commands_new.html">Commands module development version (probably broken)</a></li>
</ul>

Expand Down
6 changes: 4 additions & 2 deletions src/js/core/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ window['rangy'] = (function() {
var domRangeProperties = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed",
"commonAncestorContainer", "START_TO_START", "START_TO_END", "END_TO_START", "END_TO_END"];

// Minimal set of methods required for DOM Level 2 Range compliance
var domRangeMethods = ["setStart", "setStartBefore", "setStartAfter", "setEnd", "setEndBefore",
"setEndAfter", "collapse", "selectNode", "selectNodeContents", "compareBoundaryPoints", "deleteContents",
"extractContents", "cloneContents", "insertNode", "surroundContents", "cloneRange", "toString", "detach"];

var textRangeProperties = ["boundingHeight", "boundingLeft", "boundingTop", "boundingWidth", "htmlText", "text"];

// Subset of TextRange's full set of methods that we're interested in
var textRangeMethods = ["collapse", "compareEndPoints", "duplicate", "getBookmark", "moveToBookmark",
"moveToElementText", "parentElement", "pasteHTML", "select", "setEndPoint", "getBoundingClientRect"];
var textRangeMethods = ["collapse", "compareEndPoints", "duplicate", "moveToElementText", "parentElement", "select",
"setEndPoint", "getBoundingClientRect"];

/*----------------------------------------------------------------------------------------------------------------*/

Expand Down Expand Up @@ -107,6 +108,7 @@ window['rangy'] = (function() {

api.warn = warn;

// Add utility extend() method
if ({}.hasOwnProperty) {
api.util.extend = function(o, props) {
for (var i in props) {
Expand Down
1 change: 1 addition & 0 deletions src/js/core/wrappedselection.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ rangy.createModule("WrappedSelection", function(api, module) {
return nodes[0];
}

// Simple, quick test which only needs to distinguish between a TextRange and a ControlRange
function isTextRange(range) {
return !!range && typeof range.text != "undefined";
}
Expand Down
Loading

0 comments on commit f664afe

Please sign in to comment.