342 lines
8.9 KiB
JavaScript
342 lines
8.9 KiB
JavaScript
/** Test for Bug 1012662 **/
|
|
// This test is called from both test_bug1012662_editor.html and test_bug1012662_noeditor.html
|
|
// This is to test that the code works both in the presence of a contentEditable node, and in the absense of one
|
|
var WATCH_TIMEOUT = 300;
|
|
|
|
// Some global variables to make the debug messages easier to track down
|
|
var gTestN0 = 0, gTestN1 = 0, gTestN2 = 0;
|
|
function testLoc() { return " " + gTestN0 + " - " + gTestN1 + " - " + gTestN2; }
|
|
|
|
// Listen for cut & copy events
|
|
var gCopyCount = 0, gCutCount = 0;
|
|
document.addEventListener('copy', function() {
|
|
gCopyCount++;
|
|
});
|
|
document.addEventListener('cut', function() {
|
|
gCutCount++;
|
|
});
|
|
|
|
|
|
// Helper methods
|
|
function selectNode(aSelector, aCb) {
|
|
var dn = document.querySelector(aSelector);
|
|
var range = document.createRange();
|
|
range.selectNodeContents(dn);
|
|
window.getSelection().removeAllRanges();
|
|
window.getSelection().addRange(range);
|
|
if (aCb) {
|
|
aCb();
|
|
}
|
|
}
|
|
|
|
function selectInputNode(aSelector, aCb) {
|
|
var dn = document.querySelector(aSelector);
|
|
synthesizeMouse(dn, 10, 10, {});
|
|
SimpleTest.executeSoon(function() {
|
|
synthesizeKey("A", {accelKey: true});
|
|
SimpleTest.executeSoon(aCb);
|
|
});
|
|
}
|
|
|
|
// Callback functions for attaching to the button
|
|
function execCut(aShouldSucceed) {
|
|
var cb = function(e) {
|
|
e.preventDefault();
|
|
document.removeEventListener('keydown', cb);
|
|
|
|
is(aShouldSucceed, document.execCommand('cut'), "Keydown caused cut invocation" + testLoc());
|
|
};
|
|
return cb;
|
|
}
|
|
function execCopy(aShouldSucceed) {
|
|
var cb = function(e) {
|
|
e.preventDefault();
|
|
document.removeEventListener('keydown', cb);
|
|
|
|
is(aShouldSucceed, document.execCommand('copy'), "Keydown caused copy invocation" + testLoc());
|
|
};
|
|
return cb;
|
|
}
|
|
|
|
// The basic test set. Tries to cut/copy everything
|
|
function cutCopyAll(aDoCut, aDoCopy, aDone, aNegate, aClipOverride, aJustClipboardNegate) {
|
|
var execCommandAlwaysSucceed = !!(aClipOverride || aJustClipboardNegate);
|
|
|
|
function waitForClipboard(aCond, aSetup, aNext, aNegateOne) {
|
|
if (aClipOverride) {
|
|
aCond = aClipOverride;
|
|
aNegateOne = false;
|
|
}
|
|
if (aNegate || aNegateOne || aJustClipboardNegate) {
|
|
SimpleTest.waitForClipboard(null, aSetup, aNext, aNext, "text/unicode", WATCH_TIMEOUT, true);
|
|
} else {
|
|
SimpleTest.waitForClipboard(aCond, aSetup, aNext, aNext);
|
|
}
|
|
}
|
|
|
|
function validateCutCopy(aExpectedCut, aExpectedCopy) {
|
|
if (aNegate) {
|
|
aExpectedCut = aExpectedCopy = 0;
|
|
} // When we are negating - we always expect callbacks not to be run
|
|
|
|
is(aExpectedCut, gCutCount,
|
|
(aExpectedCut > 0 ? "Expect cut callback to run" : "Expect cut callback not to run") + testLoc());
|
|
is(aExpectedCopy, gCopyCount,
|
|
(aExpectedCopy > 0 ? "Expect copy callback to run" : "Expect copy callback not to run") + testLoc());
|
|
gCutCount = gCopyCount = 0;
|
|
}
|
|
|
|
function step(n) {
|
|
function nextStep() { step(n + 1); }
|
|
|
|
document.querySelector('span').textContent = 'span text';
|
|
document.querySelector('input[type=text]').value = 'text text';
|
|
document.querySelector('input[type=password]').value = 'password text';
|
|
document.querySelector('textarea').value = 'textarea text';
|
|
|
|
var contentEditableNode = document.querySelector('div[contentEditable=true]');
|
|
if (contentEditableNode) {
|
|
contentEditableNode.textContent = 'contenteditable text';
|
|
}
|
|
|
|
gTestN2 = n;
|
|
switch (n) {
|
|
case 0:
|
|
// copy on readonly selection
|
|
selectNode('span');
|
|
waitForClipboard("span text", function() {
|
|
aDoCopy(true);
|
|
}, nextStep);
|
|
return;
|
|
|
|
case 1:
|
|
validateCutCopy(0, 1);
|
|
|
|
// cut on readonly selection
|
|
selectNode('span');
|
|
|
|
waitForClipboard("span text", function() {
|
|
aDoCut(execCommandAlwaysSucceed);
|
|
}, nextStep, true);
|
|
return;
|
|
|
|
case 2:
|
|
validateCutCopy(1, 0);
|
|
|
|
// copy on textbox selection
|
|
selectInputNode('input[type=text]', nextStep);
|
|
return;
|
|
|
|
case 3:
|
|
waitForClipboard("text text", function() {
|
|
selectInputNode('input[type=text]', function() { aDoCopy(true); });
|
|
}, nextStep);
|
|
return;
|
|
|
|
case 4:
|
|
validateCutCopy(0, 1);
|
|
|
|
// cut on textbox selection
|
|
selectInputNode('input[type=text]', nextStep);
|
|
return;
|
|
|
|
case 5:
|
|
waitForClipboard("text text", function() {
|
|
aDoCut(true);
|
|
}, nextStep);
|
|
return;
|
|
|
|
case 6:
|
|
validateCutCopy(1, 0);
|
|
|
|
// copy on password selection
|
|
selectInputNode('input[type=password]', nextStep);
|
|
return;
|
|
|
|
case 7:
|
|
waitForClipboard(null, function() {
|
|
aDoCopy(execCommandAlwaysSucceed);
|
|
}, nextStep, true);
|
|
return;
|
|
|
|
case 8:
|
|
validateCutCopy(0, 1);
|
|
|
|
// cut on password selection
|
|
selectInputNode('input[type=password]', nextStep);
|
|
return;
|
|
|
|
case 9:
|
|
waitForClipboard(null, function() {
|
|
aDoCut(execCommandAlwaysSucceed);
|
|
}, nextStep, true);
|
|
return;
|
|
|
|
case 10:
|
|
validateCutCopy(1, 0);
|
|
|
|
// copy on textarea selection
|
|
selectInputNode('textarea', nextStep);
|
|
return;
|
|
|
|
case 11:
|
|
waitForClipboard("textarea text", function() {
|
|
aDoCopy(true);
|
|
}, nextStep);
|
|
return;
|
|
|
|
case 12:
|
|
validateCutCopy(0, 1);
|
|
|
|
// cut on password selection
|
|
selectInputNode('textarea', nextStep);
|
|
return;
|
|
|
|
case 13:
|
|
waitForClipboard("textarea text", function() {
|
|
aDoCut(true);
|
|
}, nextStep);
|
|
return;
|
|
|
|
case 14:
|
|
validateCutCopy(1, 0);
|
|
|
|
// copy on no selection
|
|
document.querySelector('textarea').blur();
|
|
|
|
waitForClipboard(null, function() {
|
|
aDoCopy(true);
|
|
}, nextStep, true);
|
|
return;
|
|
|
|
case 15:
|
|
validateCutCopy(0, 1);
|
|
|
|
// cut on no selection
|
|
waitForClipboard(null, function() {
|
|
aDoCut(execCommandAlwaysSucceed);
|
|
}, nextStep, true);
|
|
return;
|
|
|
|
case 16:
|
|
validateCutCopy(1, 0);
|
|
|
|
if (!document.querySelector('div[contentEditable=true]')) {
|
|
// We're done! (no contentEditable node!)
|
|
step(-1);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 17:
|
|
// copy on contenteditable selection
|
|
waitForClipboard("contenteditable text", function() {
|
|
selectNode('div[contentEditable=true]', function() {
|
|
aDoCopy(true);
|
|
});
|
|
}, nextStep);
|
|
return;
|
|
|
|
case 18:
|
|
validateCutCopy(0, 1);
|
|
break;
|
|
|
|
case 19:
|
|
// cut on contenteditable selection
|
|
waitForClipboard("contenteditable text", function() {
|
|
selectNode('div[contentEditable=true]', function() {
|
|
aDoCut(true);
|
|
});
|
|
}, nextStep);
|
|
return;
|
|
|
|
case 20:
|
|
validateCutCopy(1, 0);
|
|
break;
|
|
|
|
default:
|
|
aDone();
|
|
return;
|
|
}
|
|
|
|
SimpleTest.executeSoon(function() { step(n + 1); });
|
|
}
|
|
|
|
step(0);
|
|
}
|
|
|
|
function allMechanisms(aCb, aClipOverride, aNegateAll) {
|
|
function testStep(n) {
|
|
gTestN1 = n;
|
|
switch (n) {
|
|
case 0:
|
|
// Keyboard issued
|
|
cutCopyAll(function docut(aSucc) {
|
|
synthesizeKey("X", {accelKey: true});
|
|
}, function docopy(aSucc) {
|
|
synthesizeKey("C", {accelKey: true});
|
|
}, function done() { testStep(n + 1); }, false, aClipOverride, aNegateAll);
|
|
return;
|
|
|
|
case 1:
|
|
// Button issued
|
|
cutCopyAll(function docut(aSucc) {
|
|
document.addEventListener('keydown', execCut(aSucc));
|
|
synthesizeKey("Q", {});
|
|
}, function docopy(aSucc) {
|
|
document.addEventListener('keydown', execCopy(aSucc));
|
|
synthesizeKey("Q", {});
|
|
}, function done() { testStep(n + 1); }, false, aClipOverride, aNegateAll);
|
|
return;
|
|
|
|
case 2:
|
|
// Button issued
|
|
cutCopyAll(function doCut(aSucc) {
|
|
is(false, document.execCommand('cut'), "Can't directly execCommand not in a user callback");
|
|
}, function doCopy(aSucc) {
|
|
is(false, document.execCommand('copy'), "Can't directly execCommand not in a user callback");
|
|
}, function done() { testStep(n + 1); }, true, aClipOverride, aNegateAll);
|
|
return;
|
|
|
|
default:
|
|
aCb();
|
|
return;
|
|
}
|
|
|
|
SimpleTest.executeSoon(function() { testStep(n + 1); });
|
|
}
|
|
testStep(0);
|
|
}
|
|
|
|
// Run the tests
|
|
SimpleTest.waitForExplicitFinish();
|
|
SimpleTest.requestLongerTimeout(5); // On the emulator - this times out occasionally
|
|
SimpleTest.waitForFocus(function() {
|
|
function justCancel(aEvent) {
|
|
aEvent.preventDefault();
|
|
}
|
|
|
|
function override(aEvent) {
|
|
aEvent.clipboardData.setData('text/plain', 'overridden');
|
|
aEvent.preventDefault();
|
|
}
|
|
|
|
allMechanisms(function() {
|
|
gTestN0 = 1;
|
|
document.addEventListener('cut', override);
|
|
document.addEventListener('copy', override);
|
|
|
|
allMechanisms(function() {
|
|
gTestN0 = 2;
|
|
document.removeEventListener('cut', override);
|
|
document.removeEventListener('copy', override);
|
|
document.addEventListener('cut', justCancel);
|
|
document.addEventListener('copy', justCancel);
|
|
|
|
allMechanisms(function() {
|
|
SimpleTest.finish();
|
|
}, null, true);
|
|
}, 'overridden');
|
|
});
|
|
});
|