Mypal/dom/tests/mochitest/general/test_bug1012662_common.js
2019-03-11 13:26:37 +03:00

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');
});
});