--- a/implementation.js Mon Jul 18 15:48:09 2011 -0600
+++ b/implementation.js Thu Jul 21 14:49:40 2011 -0600
@@ -549,13 +549,15 @@
/////////////////////////////////////////////////
//@{
+var executionStackDepth = 0;
+
// Helper function for common behavior.
-function setupEditCommandMethod(command, prop, range) {
- // Set up our global range magic
- globalRange = null;
- if (typeof range != "undefined") {
+function editCommandMethod(command, prop, range, callback) {
+ // Set up our global range magic, but only if we're the outermost function
+ if (executionStackDepth == 0 && typeof range != "undefined") {
globalRange = range;
- } else {
+ } else if (executionStackDepth == 0) {
+ globalRange = null;
globalRange = getActiveRange();
}
@@ -575,6 +577,16 @@
&& !(prop in commands[command])) {
throw "INVALID_ACCESS_ERR";
}
+
+ executionStackDepth++;
+ try {
+ var ret = callback();
+ } catch(e) {
+ executionStackDepth--;
+ throw e;
+ }
+ executionStackDepth--;
+ return ret;
}
function myExecCommand(command, showUi, value, range) {
@@ -601,19 +613,19 @@
// "If command is not supported, raise a NOT_SUPPORTED_ERR exception."
//
// "If command has no action, raise an INVALID_ACCESS_ERR exception."
- setupEditCommandMethod(command, "action", range);
-
- // "If command is not enabled, return false."
- if (!myQueryCommandEnabled(command, range)) {
- return false;
- }
-
- // "Take the action for command, passing value to the instructions as an
- // argument."
- commands[command].action(value);
-
- // "Return true."
- return true;
+ return editCommandMethod(command, "action", range, (function(command, showUi, value) { return function() {
+ // "If command is not enabled, return false."
+ if (!myQueryCommandEnabled(command)) {
+ return false;
+ }
+
+ // "Take the action for command, passing value to the instructions as an
+ // argument."
+ commands[command].action(value);
+
+ // "Return true."
+ return true;
+ }})(command, showUi, value));
}
function myQueryCommandEnabled(command, range) {
@@ -622,17 +634,17 @@
command = command.toLowerCase();
// "If command is not supported, raise a NOT_SUPPORTED_ERR exception."
- setupEditCommandMethod(command, "action", range);
-
- // "Among commands defined in this specification, those listed in
- // Miscellaneous commands are always enabled. The other commands defined
- // here are enabled if the active range is not null, and disabled
- // otherwise."
- return ["copy", "cut", "paste", "selectall", "stylewithcss", "usecss"].indexOf(command) != -1
- || getActiveRange() !== null;
+ return editCommandMethod(command, "action", range, (function(command) { return function() {
+ // "Among commands defined in this specification, those listed in
+ // Miscellaneous commands are always enabled. The other commands defined
+ // here are enabled if the active range is not null, and disabled
+ // otherwise."
+ return ["copy", "cut", "paste", "selectall", "stylewithcss", "usecss"].indexOf(command) != -1
+ || getActiveRange() !== null;
+ }})(command));
}
-function myQueryCommandIndeterm(command, range) {
+function myQueryCommandIndeterm(command) {
// "All of these methods must treat their command argument ASCII
// case-insensitively."
command = command.toLowerCase();
@@ -641,15 +653,15 @@
//
// "If command has no indeterminacy, raise an INVALID_ACCESS_ERR
// exception."
- setupEditCommandMethod(command, "indeterm", range);
-
- // "If command is not enabled, return false."
- if (!myQueryCommandEnabled(command, range)) {
- return false;
- }
-
- // "Return true if command is indeterminate, otherwise false."
- return commands[command].indeterm();
+ return editCommandMethod(command, "indeterm", range, (function(command) { return function() {
+ // "If command is not enabled, return false."
+ if (!myQueryCommandEnabled(command)) {
+ return false;
+ }
+
+ // "Return true if command is indeterminate, otherwise false."
+ return commands[command].indeterm();
+ }})(command));
}
function myQueryCommandState(command, range) {
@@ -660,20 +672,20 @@
// "If command is not supported, raise a NOT_SUPPORTED_ERR exception."
//
// "If command has no state, raise an INVALID_ACCESS_ERR exception."
- setupEditCommandMethod(command, "state", range);
-
- // "If command is not enabled, return false."
- if (!myQueryCommandEnabled(command, range)) {
- return false;
- }
-
- // "If the state override for command is set, return it."
- if (typeof getStateOverride(command) != "undefined") {
- return getStateOverride(command);
- }
-
- // "Return true if command's state is true, otherwise false."
- return commands[command].state();
+ return editCommandMethod(command, "state", range, (function(command) { return function() {
+ // "If command is not enabled, return false."
+ if (!myQueryCommandEnabled(command)) {
+ return false;
+ }
+
+ // "If the state override for command is set, return it."
+ if (typeof getStateOverride(command) != "undefined") {
+ return getStateOverride(command);
+ }
+
+ // "Return true if command's state is true, otherwise false."
+ return commands[command].state();
+ }})(command));
}
// "When the queryCommandSupported(command) method on the HTMLDocument
@@ -695,20 +707,20 @@
// "If command is not supported, raise a NOT_SUPPORTED_ERR exception."
//
// "If command has no value, raise an INVALID_ACCESS_ERR exception."
- setupEditCommandMethod(command, "value", range);
-
- // "If command is not enabled, return the empty string."
- if (!myQueryCommandEnabled(command, range)) {
- return "";
- }
-
- // "If the value override for command is set, return it."
- if (typeof getValueOverride(command) != "undefined") {
- return getValueOverride(command);
- }
-
- // "Return command's value."
- return commands[command].value();
+ editCommandMethod(command, "value", range, function() {
+ // "If command is not enabled, return the empty string."
+ if (!myQueryCommandEnabled(command)) {
+ return "";
+ }
+
+ // "If the value override for command is set, return it."
+ if (typeof getValueOverride(command) != "undefined") {
+ return getValueOverride(command);
+ }
+
+ // "Return command's value."
+ return commands[command].value();
+ });
}
//@}
@@ -2952,7 +2964,7 @@
action: function() {
// "If queryCommandState("bold") returns true, set the selection's
// value to "normal". Otherwise set the selection's value to "bold"."
- if (myQueryCommandState("bold", getActiveRange())) {
+ if (myQueryCommandState("bold")) {
setSelectionValue("bold", "normal");
} else {
setSelectionValue("bold", "bold");
@@ -3239,7 +3251,7 @@
action: function() {
// "If queryCommandState("italic") returns true, set the selection's
// value to "normal". Otherwise set the selection's value to "italic"."
- if (myQueryCommandState("italic", getActiveRange())) {
+ if (myQueryCommandState("italic")) {
setSelectionValue("italic", "normal");
} else {
setSelectionValue("italic", "italic");
@@ -3357,7 +3369,7 @@
// "If queryCommandState("strikethrough") returns true, set the
// selection's value to null. Otherwise set the selection's value to
// "line-through"."
- if (myQueryCommandState("strikethrough", getActiveRange())) {
+ if (myQueryCommandState("strikethrough")) {
setSelectionValue("strikethrough", null);
} else {
setSelectionValue("strikethrough", "line-through");
@@ -3371,7 +3383,7 @@
commands.subscript = {
action: function() {
// "Call queryCommandState("subscript"), and let state be the result."
- var state = myQueryCommandState("subscript", getActiveRange());
+ var state = myQueryCommandState("subscript");
// "Set the selection's value to "baseline"."
setSelectionValue("subscript", "baseline");
@@ -3404,7 +3416,7 @@
action: function() {
// "Call queryCommandState("superscript"), and let state be the
// result."
- var state = myQueryCommandState("superscript", getActiveRange());
+ var state = myQueryCommandState("superscript");
// "Set the selection's value to "baseline"."
setSelectionValue("superscript", "baseline");
@@ -3438,7 +3450,7 @@
action: function() {
// "If queryCommandState("underline") returns true, set the selection's
// value to null. Otherwise set the selection's value to "underline"."
- if (myQueryCommandState("underline", getActiveRange())) {
+ if (myQueryCommandState("underline")) {
setSelectionValue("underline", null);
} else {
setSelectionValue("underline", "underline");