Skip to content

Commit

Permalink
Merging in commands module code from old 1.2 branch
Browse files Browse the repository at this point in the history
  • Loading branch information
timdown committed Jul 31, 2011
1 parent 63f62a3 commit 29fc523
Show file tree
Hide file tree
Showing 11 changed files with 2,599 additions and 161 deletions.
319 changes: 319 additions & 0 deletions demos/commands.html
@@ -0,0 +1,319 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Rangy commands demo</title>
<style type="text/css">
div.halfWidth {
float: left;
width: 48%;
padding: 5px;
}

input.unapplied {
border: solid #666 1px;
background-color: #ccc;
margin-right: 5px;
}

input.applied {
border: solid #006 1px;
background-color: #eee;
margin-right: 5px;
}
</style>
<script type="text/javascript" src="../lib/log4javascript.js"></script>
<script type="text/javascript">
var appender = new log4javascript.PopUpAppender();
log4javascript.getRootLogger().addAppender(appender);
log4javascript.setShowStackTraces(true);
//log4javascript.setEnabled(false);
</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-commands.js"></script>
<script type="text/javascript" src="../src/js/modules/commands/rangy-bold.js"></script>
<script type="text/javascript" src="../src/js/modules/commands/rangy-italic.js"></script>
<script type="text/javascript" src="../src/js/modules/commands/rangy-applyclass.js"></script>
<script type="text/javascript" src="../src/js/modules/rangy-cssclassapplier.js"></script>
<script type="text/javascript" src="../test/implementation.js"></script>
<script type="text/javascript">
var iframeDoc, iframeWin, contentHtmlTextArea, mainLoaded = false, iframeLoaded = false;
var greenBorderCssClassApplier, boldRedCssClassApplier;

function updateContentHtml() {
contentHtmlTextArea.value = iframeDoc.body.innerHTML;
}

function allLoaded() {
updateContentHtml();
}

// This is good enough for our target browsers
function addEvent(obj, eventType, listener) {
if (typeof obj.addEventListener != "undefined") {
obj.addEventListener(eventType, listener, false);
} else if (typeof obj.attachEvent != "undefined") {
obj.attachEvent("on" + eventType, listener);
}
}

function execCommand(commandName, options) {
options.document = iframeDoc;
rangy.execCommand(commandName, options);

updateContentHtml();
iframeWin.focus();
}

function initTextareaIframeSync() {
var timer = null;
addEvent(iframeDoc, "keyup", function() {
if (timer) {
window.clearTimeout(timer);
}
timer = window.setTimeout(function() {
timer = null;
updateContentHtml();
}, 1000);
});

contentHtmlTextArea.onchange = function() {
iframeDoc.body.innerHTML = contentHtmlTextArea.value;
};
}

var toolUpdaters = [];

function initToolUpdates() {
var timer = null;

function doUpdate() {
for (var i = 0, len = toolUpdaters.length; i < len; ++i) {
toolUpdaters[i]();
}
}

function debouncedEventHandler() {
if (timer) {
window.clearTimeout(timer);
}
timer = window.setTimeout(function() {
timer = null;
doUpdate();
}, 50);
}

if ("onselectionchange" in iframeDoc) {
addEvent(iframeDoc, "selectionchange", debouncedEventHandler);
} else {
addEvent(iframeDoc, "keyup", debouncedEventHandler);
addEvent(iframeDoc, "mouseup", debouncedEventHandler);
}
}

function createButton(text, commandName, options, isAppliedFunc) {
var button = document.createElement("input");
button.type = "button";
button.value = text;
button.className = "unapplied";

var updater = function() {
button.className = (isAppliedFunc && isAppliedFunc()) ? "applied" : "unapplied";
};

toolUpdaters.push(updater);

button.onclick = function() {
execCommand(commandName, options);
updater();
};

document.getElementById("toolbar").appendChild(button);
}

window.onload = function() {
rangy.init();
iframeWin = rangy.dom.getIframeWindow( document.getElementById("content") );
iframeDoc = iframeWin.document;
contentHtmlTextArea = document.getElementById("contentHtml");
mainLoaded = true;
if (iframeLoaded) {
allLoaded();
}

// Update the source textarea after changes in the WYSIWYG iframe and vice versa
initTextareaIframeSync();

// Update toolbar when the selection changes
initToolUpdates();

// Create buttons
var boldCssOptions = {
document: iframeDoc,
styleWithCss: true
};

createButton("Bold (CSS)", "bold", boldCssOptions,
function() {
return rangy.queryCommandValue("bold", boldCssOptions);
}
);

var boldBOptions = {
document: iframeDoc,
styleWithCss: false,
tagName: "b"
};

createButton("Bold (b)", "bold", boldBOptions,
function() {
return rangy.queryCommandValue("bold", boldBOptions);
}
);

var boldStrongOptions = {
document: iframeDoc,
styleWithCss: false,
tagName: "b"
};

createButton("Bold (strong)", "bold", boldStrongOptions,
function() {
return rangy.queryCommandValue("bold", boldStrongOptions);
}
);

var italicCssOptions = {
document: iframeDoc,
styleWithCss: true
};

createButton("Italic (CSS)", "italic", italicCssOptions,
function() {
return rangy.queryCommandValue("italic", italicCssOptions);
}
);

var italicIOptions = {
document: iframeDoc,
styleWithCss: false
};

createButton("Italic (i)", "italic", italicIOptions,
function() {
return rangy.queryCommandValue("italic", italicIOptions);
}
);

/*
greenBorderCssClassApplier = rangy.createCssClassApplier("greenBorder");
boldRedCssClassApplier = rangy.createCssClassApplier("boldRed");
*/
};

// Iframe load callback
window.contentLoadCallback = function() {
iframeLoaded = true;
if (mainLoaded) {
allLoaded();
}
};

function nativeBold(css) {
iframeDoc.execCommand("StyleWithCSS", false, css);
iframeDoc.execCommand("bold", false, null);
updateContentHtml();
iframeWin.focus();
}

function aryehBold() {
var sel = rangy.getSelection(iframeDoc.defaultView);

iframeDoc.body.contentEditable = true;
aryeh.execCommand("stylewithcss", false, true);
aryeh.execCommand("bold", false, null, rangy.getSelection(iframeDoc.defaultView).getRangeAt(0));
iframeDoc.body.contentEditable = false;

updateContentHtml();
iframeWin.focus();
}
/*
function bold(styleWithCss, tagName) {
rangy.execCommand("bold", {
document: iframeDoc,
styleWithCss: styleWithCss,
tagName: tagName
});
updateContentHtml();
iframeWin.focus();
}
function italic(styleWithCss) {
rangy.execCommand("italic", {
document: iframeDoc,
styleWithCss: styleWithCss
});
updateContentHtml();
iframeWin.focus();
}
function applyClass(className) {
rangy.execCommand("applyClass", {
document: iframeDoc,
value: className
});
updateContentHtml();
iframeWin.focus();
}
function applyClassCssClassApplier(className) {
var applier = (className == "boldRed") ? boldRedCssClassApplier : greenBorderCssClassApplier;
applier.toggleSelection(iframeWin);
updateContentHtml();
iframeWin.focus();
}
*/
</script>

</head>
<h1>Rangy commands demo</h1>
<p>
Use the buttons to test the available commands. Both panes (WYSIWYG and HTML) are editable (HTML textarea uses
<code>onchange</code>, so click outside or tab away to get the WYSIWYG pane to update).
</p>
<div class="halfWidth">
WYSIWYG:
<div style="border: solid gray 1px">
<div style="background-color: #999; padding: 2px" id="toolbar">
<input type="button" onclick="nativeBold(true);" value="Bold (native, CSS)">
<input type="button" onclick="nativeBold(false);" value="Bold (native, no CSS)">
<!--
<input type="button" onclick="aryehBold();" value="Bold (Aryeh)">
<input type="button" onclick="bold(true);" value="Bold/CSS">
<input type="button" onclick="bold(false, 'b');" value="Bold/B">
<input type="button" onclick="bold(false, 'strong');" value="Bold/strong">
<input type="button" onclick="nativeBold();" value="Bold (native)">
<input type="button" onclick="italic(true);" value="Italic/CSS">
<input type="button" onclick="italic(false);" value="Italic">
<input type="button" onclick="applyClass('greenBorder');" value="Green border">
<input type="button" onclick="applyClass('boldRed');" value="Bold red">
<input type="button" onclick="applyClassCssClassApplier('greenBorder');" value="Green border (CssClassApplier)">
<input type="button" onclick="applyClassCssClassApplier('boldRed');" value="Bold red (CssClassApplier)">
-->
</div>
<iframe id="content" src="content.html?1" style="width: 100%; height: 400px" frameborder="0"></iframe>
</div>
</div>
<div class="halfWidth">
HTML:
<textarea style="width: 98%; height: 420px; font-size: 0.75em; font-family: Courier New, Monospace" id="contentHtml"></textarea>
</div>
<body>
</body>
</html>
74 changes: 74 additions & 0 deletions demos/content.html
@@ -0,0 +1,74 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Rangy Bold Demo</title>
<style type="text/css">
*.greenBorder {
font-style: italic;
border: solid green 1px;
color: purple;
}

*.boldRed {
font-weight: bold;
color: red;
background-color: yellow;
}
</style>
<script type="text/javascript">
window.onload = function() {
var callback;
if ( (callback = window.parent.contentLoadCallback) ) {
callback();
}
}
</script>
</head>
<body contenteditable="true">
<div> <span>Test</span> </div>
<div> <span>Test</span> </div>
<div>Test</div>

<p> <i>2</i> </p>
<div><p>One</p>
<span>Two</span>
<p>Three</p></div>

<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 <span style="font-weight: bold; font-style: italic">11 players</span> 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</h2>
<p>
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</h2>
<pre>
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 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>

0 comments on commit 29fc523

Please sign in to comment.