Bug 788458 - Fix issues with copy / paste in rule and computed views; r=dcamp

This commit is contained in:
Michael Ratcliffe 2012-10-01 12:59:23 +01:00
Родитель 56f8757dee
Коммит 6167a1a008
2 изменённых файлов: 96 добавлений и 69 удалений

Просмотреть файл

@ -1124,12 +1124,16 @@ CssRuleView.prototype = {
*/
_onMenuUpdate: function CssRuleView_onMenuUpdate(aEvent)
{
let node = this.doc.popupNode;
// Copy selection.
let disable = this.doc.defaultView.getSelection().isCollapsed;
let editorSelection = node.className == "styleinspector-propertyeditor" &&
node.selectionEnd - node.selectionStart != 0;
let disable = this.doc.defaultView.getSelection().isCollapsed &&
!editorSelection;
this._copyItem.disabled = disable;
// Copy property, copy property name & copy property value.
let node = this.doc.popupNode;
if (!node) {
return;
}
@ -1159,16 +1163,26 @@ CssRuleView.prototype = {
*/
_onCopy: function CssRuleView_onCopy(aEvent)
{
let win = this.doc.defaultView;
let text = win.getSelection().toString();
let target = this.doc.popupNode || aEvent.target;
let text;
// Remove any double newlines.
text = text.replace(/(\r?\n)\r?\n/g, "$1");
if (target.nodeName == "input") {
let start = Math.min(target.selectionStart, target.selectionEnd);
let end = Math.max(target.selectionStart, target.selectionEnd);
let count = end - start;
text = target.value.substr(start, count);
} else {
let win = this.doc.defaultView;
text = win.getSelection().toString();
// Remove "inline"
let inline = _strings.GetStringFromName("rule.sourceInline");
let rx = new RegExp("^" + inline + "\\r?\\n?", "g");
text = text.replace(rx, "");
// Remove any double newlines.
text = text.replace(/(\r?\n)\r?\n/g, "$1");
// Remove "inline"
let inline = _strings.GetStringFromName("rule.sourceInline");
let rx = new RegExp("^" + inline + "\\r?\\n?", "g");
text = text.replace(rx, "");
}
clipboardHelper.copyString(text, this.doc);
@ -1277,12 +1291,13 @@ CssRuleView.prototype = {
_onCopyProperty: function CssRuleView_onCopyProperty(aEvent)
{
let node = this.doc.popupNode;
if (!node) {
return;
}
if (!node.classList.contains("ruleview-propertyname")) {
node = node.querySelector(".ruleview-propertyname");
node = node.parentNode.parentNode.querySelector(".ruleview-propertyname");
}
if (node) {
@ -1303,7 +1318,7 @@ CssRuleView.prototype = {
}
if (!node.classList.contains("ruleview-propertyvalue")) {
node = node.querySelector(".ruleview-propertyvalue");
node = node.parentNode.parentNode.querySelector(".ruleview-propertyvalue");
}
if (node) {
@ -1381,6 +1396,19 @@ RuleEditor.prototype = {
}
}.bind(this), false);
this.element.addEventListener("mousedown", function() {
let editorNodes =
this.doc.querySelectorAll(".styleinspector-propertyeditor");
if (editorNodes) {
for (let node of editorNodes) {
if (node.inplaceEditor) {
node.inplaceEditor._clear();
}
}
}
}.bind(this), false);
this.propertyList = createChild(code, "ul", {
class: "ruleview-propertylist"
});

Просмотреть файл

@ -88,8 +88,8 @@ function testClip()
SimpleTest.waitForClipboard(function IUI_boundCopyPropCheck() {
return checkClipboardData(expectedPattern);
},
checkCopyRule, checkCopyRuleWithEditorSelected, function() {
failedClipboard(expectedPattern, checkCopyRuleWithEditorSelected);
checkCopyRule, checkCopyProperty, function() {
failedClipboard(expectedPattern, checkCopyProperty);
});
});
}
@ -118,57 +118,6 @@ function checkCopyRule() {
menu.hidePopup();
}
function checkCopyRuleWithEditorSelected()
{
let contentDoc = ruleViewFrame().contentDocument;
let rules = contentDoc.querySelectorAll(".ruleview-rule");
let propNodes = contentDoc.querySelectorAll(".ruleview-property");
let propNode = propNodes[2];
let propNameNode = propNode.querySelector(".ruleview-propertyname");
ok(propNameNode, "we have the property name node");
info("Checking that _boundCopyRule() returns the correct clipboard value");
let expectedPattern = "element {[\\r\\n]+" +
" margin: 10em;[\\r\\n]+" +
" font-size: 14pt;[\\r\\n]+" +
" font-family: helvetica,sans-serif;[\\r\\n]+" +
" color: rgb\\(170, 170, 170\\);[\\r\\n]+" +
"}[\\r\\n]*";
let elementRuleEditor = rules[0]._ruleEditor;
waitForEditorFocus(elementRuleEditor.element, function onNewElement(aEditor) {
ok(aEditor, "we have the editor");
waitForBlur.editor = aEditor;
// We need the context menu to open in the correct place in order for
// popupNode to be propertly set.
EventUtils.synthesizeMouse(aEditor.input, 1, 1,
{ type: "contextmenu", button: 2 }, ruleViewFrame().contentWindow);
SimpleTest.waitForClipboard(function IUI_boundCopyCheckWithSelection() {
let menu = contentDoc.querySelector("#rule-view-context-menu");
ok(menu, "we have the context menu");
menu.hidePopup();
return checkClipboardData(expectedPattern);
}, ruleView()._boundCopyRule, waitForBlur, function() {
failedClipboard(expectedPattern, checkCopyProperty);
});
});
EventUtils.synthesizeMouse(propNameNode, 1, 1, { }, ruleViewFrame().contentWindow);
}
function waitForBlur()
{
waitForEditorBlur(waitForBlur.editor, function() {
waitForBlur.editor = null;
checkCopyProperty();
});
waitForBlur.editor.input.blur();
}
function checkCopyProperty()
{
let contentDoc = ruleViewFrame().contentDocument;
@ -197,7 +146,7 @@ function checkCopyPropertyName()
{
info("Checking that _onCopyProperty() returns " +
"the correct clipboard value");
let expectedPattern = "font-family";
let expectedPattern = "margin";
SimpleTest.waitForClipboard(function IUI_boundCopyPropNameCheck() {
return checkClipboardData(expectedPattern);
@ -212,7 +161,7 @@ function checkCopyPropertyValue()
{
info("Checking that _onCopyPropertyValue() " +
" returns the correct clipboard value");
let expectedPattern = "helvetica,sans-serif";
let expectedPattern = "10em";
SimpleTest.waitForClipboard(function IUI_boundCopyPropValueCheck() {
return checkClipboardData(expectedPattern);
@ -248,11 +197,61 @@ function checkCopySelection()
SimpleTest.waitForClipboard(function IUI_boundCopyCheck() {
return checkClipboardData(expectedPattern);
},ruleView()._boundCopy, finishup, function() {
failedClipboard(expectedPattern, finishup);
},ruleView()._boundCopy, testSimpleCopy, function() {
failedClipboard(expectedPattern, testSimpleCopy);
});
}
function testSimpleCopy()
{
executeSoon(function() {
info("Checking that _onCopy() returns the correct clipboard value");
let expectedPattern = "element {[\\r\\n]+" +
" margin: 10em;[\\r\\n]+" +
" font-size: 14pt;[\\r\\n]+" +
" font-family: helvetica,sans-serif;[\\r\\n]+" +
" color: rgb\\(170, 170, 170\\);[\\r\\n]+" +
"}[\\r\\n]*";
SimpleTest.waitForClipboard(function IUI_testSimpleCopy() {
return checkClipboardData(expectedPattern);
},
checkSimpleCopy, finishup, function() {
failedClipboard(expectedPattern, finishup);
});
});
}
function checkSimpleCopy() {
let contentDoc = ruleViewFrame().contentDocument;
let props = contentDoc.querySelectorAll(".ruleview-code");
is(props.length, 2, "checking property length");
let prop = props[0];
selectNode(prop);
// We need the context menu to open in the correct place in order for
// popupNode to be propertly set.
EventUtils.synthesizeMouse(prop, 1, 1, { type: "contextmenu", button: 2 },
ruleViewFrame().contentWindow);
ruleView()._boundCopy();
let menu = contentDoc.querySelector("#rule-view-context-menu");
ok(menu, "we have the context menu");
menu.hidePopup();
}
function selectNode(aNode) {
let doc = aNode.ownerDocument;
let win = doc.defaultView;
let range = doc.createRange();
range.selectNode(aNode);
win.getSelection().addRange(range);
}
function checkClipboardData(aExpectedPattern)
{
let actual = SpecialPowers.getClipboardData("text/unicode");