Merge mozilla-central and fx-team

This commit is contained in:
Ed Morley 2013-08-20 12:12:43 +01:00
commit 0398833aaa
13 changed files with 353 additions and 178 deletions

View File

@ -49,7 +49,11 @@ const EXPECTED_REFLOWS = [
// tabPreviews.capture()
"tabPreviews_capture@chrome://browser/content/browser.js|" +
"tabPreviews_handleEvent/<@chrome://browser/content/browser.js|"
"tabPreviews_handleEvent/<@chrome://browser/content/browser.js|",
// tabPreviews.capture()
"tabPreviews_capture@chrome://browser/content/browser.js|" +
"@chrome://browser/content/browser.js|"
];
const PREF_PRELOAD = "browser.newtab.preload";

View File

@ -1219,81 +1219,102 @@ ElementEditor.prototype = {
return this.node.startModifyingAttributes();
},
_createAttribute: function EE_createAttribute(aAttr, aBefore)
_createAttribute: function EE_createAttribute(aAttr, aBefore = null)
{
if (this.attrs.hasOwnProperty(aAttr.name)) {
var attr = this.attrs[aAttr.name];
var name = attr.querySelector(".attrname");
var val = attr.querySelector(".attrvalue");
} else {
// Create the template editor, which will save some variables here.
let data = {
attrName: aAttr.name,
};
this.template("attribute", data);
var {attr, inner, name, val} = data;
// Create the template editor, which will save some variables here.
let data = {
attrName: aAttr.name,
};
this.template("attribute", data);
var {attr, inner, name, val} = data;
// Figure out where we should place the attribute.
let before = aBefore || null;
if (aAttr.name == "id") {
before = this.attrList.firstChild;
} else if (aAttr.name == "class") {
let idNode = this.attrs["id"];
before = idNode ? idNode.nextSibling : this.attrList.firstChild;
}
this.attrList.insertBefore(attr, before);
// Double quotes need to be handled specially to prevent DOMParser failing.
// name="v"a"l"u"e" when editing -> name='v"a"l"u"e"'
// name="v'a"l'u"e" when editing -> name="v'a&quot;l'u&quot;e"
let editValueDisplayed = aAttr.value;
let hasDoubleQuote = editValueDisplayed.contains('"');
let hasSingleQuote = editValueDisplayed.contains("'");
let initial = aAttr.name + '="' + editValueDisplayed + '"';
// Make the attribute editable.
editableField({
element: inner,
trigger: "dblclick",
stopOnReturn: true,
selectAll: false,
contentType: InplaceEditor.CONTENT_TYPES.CSS_MIXED,
popup: this.markup.popup,
start: (aEditor, aEvent) => {
// If the editing was started inside the name or value areas,
// select accordingly.
if (aEvent && aEvent.target === name) {
aEditor.input.setSelectionRange(0, name.textContent.length);
} else if (aEvent && aEvent.target === val) {
let length = val.textContent.length;
let editorLength = aEditor.input.value.length;
let start = editorLength - (length + 1);
aEditor.input.setSelectionRange(start, start + length);
} else {
aEditor.input.select();
}
},
done: (aVal, aCommit) => {
if (!aCommit) {
return;
}
let doMods = this._startModifyingAttributes();
let undoMods = this._startModifyingAttributes();
// Remove the attribute stored in this editor and re-add any attributes
// parsed out of the input element. Restore original attribute if
// parsing fails.
try {
this._saveAttribute(aAttr.name, undoMods);
doMods.removeAttribute(aAttr.name);
this._applyAttributes(aVal, attr, doMods, undoMods);
this.undo.do(() => {
doMods.apply();
}, () => {
undoMods.apply();
})
} catch(ex) {
console.error(ex);
}
}
});
this.attrs[aAttr.name] = attr;
// Can't just wrap value with ' since the value contains both " and '.
if (hasDoubleQuote && hasSingleQuote) {
editValueDisplayed = editValueDisplayed.replace(/\"/g, "&quot;");
initial = aAttr.name + '="' + editValueDisplayed + '"';
}
// Wrap with ' since there are no single quotes in the attribute value.
if (hasDoubleQuote && !hasSingleQuote) {
initial = aAttr.name + "='" + editValueDisplayed + "'";
}
// Make the attribute editable.
editableField({
element: inner,
trigger: "dblclick",
stopOnReturn: true,
selectAll: false,
initial: initial,
contentType: InplaceEditor.CONTENT_TYPES.CSS_MIXED,
popup: this.markup.popup,
start: (aEditor, aEvent) => {
// If the editing was started inside the name or value areas,
// select accordingly.
if (aEvent && aEvent.target === name) {
aEditor.input.setSelectionRange(0, name.textContent.length);
} else if (aEvent && aEvent.target === val) {
let length = editValueDisplayed.length;
let editorLength = aEditor.input.value.length;
let start = editorLength - (length + 1);
aEditor.input.setSelectionRange(start, start + length);
} else {
aEditor.input.select();
}
},
done: (aVal, aCommit) => {
if (!aCommit) {
return;
}
let doMods = this._startModifyingAttributes();
let undoMods = this._startModifyingAttributes();
// Remove the attribute stored in this editor and re-add any attributes
// parsed out of the input element. Restore original attribute if
// parsing fails.
try {
this._saveAttribute(aAttr.name, undoMods);
doMods.removeAttribute(aAttr.name);
this._applyAttributes(aVal, attr, doMods, undoMods);
this.undo.do(() => {
doMods.apply();
}, () => {
undoMods.apply();
})
} catch(ex) {
console.error(ex);
}
}
});
// Figure out where we should place the attribute.
let before = aBefore;
if (aAttr.name == "id") {
before = this.attrList.firstChild;
} else if (aAttr.name == "class") {
let idNode = this.attrs["id"];
before = idNode ? idNode.nextSibling : this.attrList.firstChild;
}
this.attrList.insertBefore(attr, before);
// Remove the old version of this attribute from the DOM.
let oldAttr = this.attrs[aAttr.name];
if (oldAttr && oldAttr.parentNode) {
oldAttr.parentNode.removeChild(oldAttr);
}
this.attrs[aAttr.name] = attr;
name.textContent = aAttr.name;
val.textContent = aAttr.value;

View File

@ -40,5 +40,7 @@
<div id="retag-me-2"></div>
</div>
<div id="node25"></div>
<div id="node26" style='background-image: url("moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.org%2F");'></div>
<div id="node27" class="Double &quot; and single &apos;"></div>
</body>
</html>

View File

@ -239,6 +239,79 @@ function test() {
});
}
},
{
desc: "Modify inline style containing \"",
before: function() {
assertAttributes(doc.querySelector("#node26"), {
id: "node26",
style: 'background-image: url("moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.org%2F");'
});
},
execute: function(after) {
inspector.once("markupmutation", after);
let editor = getContainerForRawNode(markup, doc.querySelector("#node26")).editor;
let attr = editor.attrs["style"].querySelector(".editable");
attr.focus();
EventUtils.sendKey("return", inspector.panelWin);
let input = inplaceEditor(attr).input;
let value = input.value;
is (value,
"style='background-image: url(\"moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.org%2F\");'",
"Value contains actual double quotes"
);
value = value.replace(/mozilla\.org/, "mozilla.com");
input.value = value;
EventUtils.sendKey("return", inspector.panelWin);
},
after: function() {
assertAttributes(doc.querySelector("#node26"), {
id: "node26",
style: 'background-image: url("moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.com%2F");'
});
}
},
{
desc: "Modify inline style containing \" and \'",
before: function() {
assertAttributes(doc.querySelector("#node27"), {
id: "node27",
class: 'Double " and single \''
});
},
execute: function(after) {
inspector.once("markupmutation", after);
let editor = getContainerForRawNode(markup, doc.querySelector("#node27")).editor;
let attr = editor.attrs["class"].querySelector(".editable");
attr.focus();
EventUtils.sendKey("return", inspector.panelWin);
let input = inplaceEditor(attr).input;
let value = input.value;
is (value, "class=\"Double &quot; and single '\"", "Value contains &quot;");
value = value.replace(/Double/, "&quot;").replace(/single/, "'");
input.value = value;
EventUtils.sendKey("return", inspector.panelWin);
},
after: function() {
assertAttributes(doc.querySelector("#node27"), {
id: "node27",
class: '" " and \' \''
});
}
},
{
desc: "Add an attribute value without closing \"",
enteredText: 'style="display: block;',

View File

@ -687,6 +687,7 @@ ResponsiveUI.prototype = {
this.stack.removeAttribute("notransition");
}
this.ignoreY = false;
this.ignoreX = false;
this.isResizing = false;
},

View File

@ -42,7 +42,7 @@ function simpleInherit(aInspector, aRuleView)
styleNode.parentNode.removeChild(styleNode);
emptyInherit();
}).then(null, console.error);
});
}
function emptyInherit()
@ -68,7 +68,7 @@ function emptyInherit()
styleNode.parentNode.removeChild(styleNode);
elementStyleInherit();
}).then(null, console.error);
});
}
function elementStyleInherit()
@ -92,7 +92,7 @@ function elementStyleInherit()
is(inheritProp.name, "color", "color should have been inherited.");
finishTest();
}).then(null, console.error);
});
}
function finishTest()

View File

@ -37,7 +37,7 @@ function SI_inspectNode()
is(span, computedView.viewedElement.rawNode(),
"style inspector node matches the selected node");
SI_toggleDefaultStyles();
}).then(null, (err) => console.error(err));
});
}
function SI_toggleDefaultStyles()

View File

@ -60,7 +60,7 @@
<!ENTITY btnPageJS.accesskey "J">
<!ENTITY btnPageSecurity.label "Security">
<!ENTITY btnPageSecurity.tooltip "Log security errors and warnings">
<!ENTITY btnPageSecurity.accesskey "S">
<!ENTITY btnPageSecurity.accesskey "u">
<!-- LOCALIZATION NOTE (btnPageLogging): This is used as the text of the
- the toolbar. It shows or hides messages that the web developer inserted on

View File

@ -9,12 +9,6 @@
.newattr {
cursor: pointer;
}
/* Give some padding to focusable elements to match the editor input
* that will replace them. */
span[tabindex] {
display: inline-block;
padding: 1px 0;
}

View File

@ -28,8 +28,11 @@ NoFilesSelected=No files selected.
# %S will be a number greater or equal to 2.
XFilesSelected=%S files selected.
ColorPicker=Choose a color
# LOCALIZATION NOTE (AndXMoreFiles): this string is shown at the end of the
# tooltip text for <input type='file' multiple> when there are more than 21
# files selected (when we will only list the first 20, plus an "and X more"
# line). %S will be the number of files minus 20.
AndXMoreFiles=and %S more
# LOCALIZATION NOTE (AndNMoreFiles): Semi-colon list of plural forms.
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# This string is shown at the end of the tooltip text for <input type='file'
# multiple> when there are more than 21 files selected (when we will only list
# the first 20, plus an "and X more" line). #1 represents the number of files
# minus 20 and will always be a number equal to or greater than 2. So the
# singular case will never be used.
AndNMoreFiles=and one more;and #1 more

View File

@ -590,11 +590,11 @@
if (files.length == TRUNCATED_FILE_COUNT + 1) {
titleText += "\n" + files[TRUNCATED_FILE_COUNT].name;
} else if (files.length > TRUNCATED_FILE_COUNT + 1) {
let xmoreStr = bundle.GetStringFromName("AndXMoreFiles");
let xmoreStr = bundle.GetStringFromName("AndNMoreFiles");
let xmoreNum = files.length - TRUNCATED_FILE_COUNT;
let tmp = {};
Components.utils.import("resource://gre/modules/PluralForm.jsm", tmp);
let andXMoreStr = tmp.PluralForm.get(xmoreNum, xmoreStr).replace("%S", xmoreNum);
let andXMoreStr = tmp.PluralForm.get(xmoreNum, xmoreStr).replace("#1", xmoreNum);
titleText += "\n" + andXMoreStr;
}
}

View File

@ -535,7 +535,7 @@ function timeSinceTraceStarted({ startTime }) {
* The type of completion value to serialize (return, throw, or yield).
*/
function serializeCompletionValue(aType, { value }) {
if (typeof value[aType] === "undefined") {
if (!Object.hasOwnProperty.call(value, aType)) {
return undefined;
}
return createValueGrip(value[aType], true);

View File

@ -2,8 +2,8 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that objects are correctly serialized and sent in exitedFrame
* packets.
* Tests that values are correctly serialized and sent in enteredFrame
* and exitedFrame packets.
*/
let {defer} = devtools.require("sdk/core/promise");
@ -30,73 +30,8 @@ function run_test()
function test_enter_exit_frame()
{
gTraceClient.addListener("exitedFrame", function(aEvent, aPacket) {
if (aPacket.sequence === 3) {
let obj = aPacket.return;
do_check_eq(typeof obj, "object",
'exitedFrame response should have return value');
do_check_eq(typeof obj.prototype, "object",
'return value should have prototype');
do_check_eq(typeof obj.ownProperties, "object",
'return value should have ownProperties list');
do_check_eq(typeof obj.safeGetterValues, "object",
'return value should have safeGetterValues');
do_check_eq(typeof obj.ownProperties.num, "object",
'return value should have property "num"');
do_check_eq(typeof obj.ownProperties.str, "object",
'return value should have property "str"');
do_check_eq(typeof obj.ownProperties.bool, "object",
'return value should have property "bool"');
do_check_eq(typeof obj.ownProperties.undef, "object",
'return value should have property "undef"');
do_check_eq(typeof obj.ownProperties.undef.value, "object",
'return value property "undef" should be a grip');
do_check_eq(typeof obj.ownProperties.nil, "object",
'return value should have property "nil"');
do_check_eq(typeof obj.ownProperties.nil.value, "object",
'return value property "nil" should be a grip');
do_check_eq(typeof obj.ownProperties.obj, "object",
'return value should have property "obj"');
do_check_eq(typeof obj.ownProperties.obj.value, "object",
'return value property "obj" should be a grip');
do_check_eq(typeof obj.ownProperties.arr, "object",
'return value should have property "arr"');
do_check_eq(typeof obj.ownProperties.arr.value, "object",
'return value property "arr" should be a grip');
do_check_eq(typeof obj.ownProperties.inf, "object",
'return value should have property "inf"');
do_check_eq(typeof obj.ownProperties.inf.value, "object",
'return value property "inf" should be a grip');
do_check_eq(typeof obj.ownProperties.ninf, "object",
'return value should have property "ninf"');
do_check_eq(typeof obj.ownProperties.ninf.value, "object",
'return value property "ninf" should be a grip');
do_check_eq(typeof obj.ownProperties.nan, "object",
'return value should have property "nan"');
do_check_eq(typeof obj.ownProperties.nan.value, "object",
'return value property "nan" should be a grip');
do_check_eq(typeof obj.ownProperties.nzero, "object",
'return value should have property "nzero"');
do_check_eq(typeof obj.ownProperties.nzero.value, "object",
'return value property "nzero" should be a grip');
do_check_eq(obj.prototype.type, "object");
do_check_eq(obj.ownProperties.num.value, 25);
do_check_eq(obj.ownProperties.str.value, "foo");
do_check_eq(obj.ownProperties.bool.value, false);
do_check_eq(obj.ownProperties.undef.value.type, "undefined");
do_check_eq(obj.ownProperties.nil.value.type, "null");
do_check_eq(obj.ownProperties.obj.value.type, "object");
do_check_eq(obj.ownProperties.obj.value.class, "Object");
do_check_eq(obj.ownProperties.arr.value.type, "object");
do_check_eq(obj.ownProperties.arr.value.class, "Array");
do_check_eq(obj.ownProperties.inf.value.type, "Infinity");
do_check_eq(obj.ownProperties.ninf.value.type, "-Infinity");
do_check_eq(obj.ownProperties.nan.value.type, "NaN");
do_check_eq(obj.ownProperties.nzero.value.type, "-0");
}
});
gTraceClient.addListener("enteredFrame", check_packet);
gTraceClient.addListener("exitedFrame", check_packet);
start_trace()
.then(eval_code)
@ -109,32 +44,45 @@ function test_enter_exit_frame()
function start_trace()
{
let deferred = defer();
gTraceClient.startTrace(["return"], null, function() { deferred.resolve(); });
gTraceClient.startTrace(["arguments", "return"], null, function() { deferred.resolve(); });
return deferred.promise;
}
function eval_code()
{
gDebuggee.eval("(" + function() {
function foo() {
let obj = {};
obj.self = obj;
return {
num: 25,
str: "foo",
bool: false,
undef: undefined,
nil: null,
obj: obj,
arr: [1,2,3,4,5],
inf: Infinity,
ninf: -Infinity,
nan: NaN,
nzero: -0
};
function identity(x) {
return x;
}
foo();
let circular = {};
circular.self = circular;
let obj = {
num: 0,
str: "foo",
bool: false,
undef: undefined,
nil: null,
inf: Infinity,
ninf: -Infinity,
nan: NaN,
nzero: -0,
obj: circular,
arr: [1,2,3,4,5]
};
identity();
identity(0);
identity("");
identity(false);
identity(undefined);
identity(null);
identity(Infinity);
identity(-Infinity);
identity(NaN);
identity(-0);
identity(obj);
} + ")()");
}
@ -144,3 +92,132 @@ function stop_trace()
gTraceClient.stopTrace(null, function() { deferred.resolve(); });
return deferred.promise;
}
function check_packet(aEvent, aPacket)
{
let value = (aPacket.type === "enteredFrame" && aPacket.arguments)
? aPacket.arguments[0]
: aPacket.return;
switch(aPacket.sequence) {
case 2:
do_check_eq(typeof aPacket.arguments, "object",
"zero-argument function call should send arguments list");
do_check_eq(aPacket.arguments.length, 0,
"zero-argument function call should send zero-length arguments list");
break;
case 3:
check_value(value, "object", "undefined");
break;
case 4:
case 5:
check_value(value, "number", 0);
break;
case 6:
case 7:
check_value(value, "string", "");
break;
case 8:
case 9:
check_value(value, "boolean", false);
break;
case 10:
case 11:
check_value(value, "object", "undefined");
break;
case 12:
case 13:
check_value(value, "object", "null");
break;
case 14:
case 15:
check_value(value, "object", "Infinity");
break;
case 16:
case 17:
check_value(value, "object", "-Infinity");
break;
case 18:
case 19:
check_value(value, "object", "NaN");
break;
case 20:
case 21:
check_value(value, "object", "-0");
break;
case 22:
case 23:
check_object(aPacket.type, value);
break;
}
}
function check_value(aActual, aExpectedType, aExpectedValue)
{
do_check_eq(typeof aActual, aExpectedType);
do_check_eq(aExpectedType === "object" ? aActual.type : aActual, aExpectedValue);
}
function check_object(aType, aObj) {
do_check_eq(typeof aObj, "object",
'serialized object should be present in packet');
do_check_eq(typeof aObj.prototype, "object",
'serialized object should have prototype');
do_check_eq(typeof aObj.ownProperties, "object",
'serialized object should have ownProperties list');
do_check_eq(typeof aObj.safeGetterValues, "object",
'serialized object should have safeGetterValues');
do_check_eq(typeof aObj.ownProperties.num, "object",
'serialized object should have property "num"');
do_check_eq(typeof aObj.ownProperties.str, "object",
'serialized object should have property "str"');
do_check_eq(typeof aObj.ownProperties.bool, "object",
'serialized object should have property "bool"');
do_check_eq(typeof aObj.ownProperties.undef, "object",
'serialized object should have property "undef"');
do_check_eq(typeof aObj.ownProperties.undef.value, "object",
'serialized object property "undef" should be a grip');
do_check_eq(typeof aObj.ownProperties.nil, "object",
'serialized object should have property "nil"');
do_check_eq(typeof aObj.ownProperties.nil.value, "object",
'serialized object property "nil" should be a grip');
do_check_eq(typeof aObj.ownProperties.obj, "object",
'serialized object should have property "aObj"');
do_check_eq(typeof aObj.ownProperties.obj.value, "object",
'serialized object property "aObj" should be a grip');
do_check_eq(typeof aObj.ownProperties.arr, "object",
'serialized object should have property "arr"');
do_check_eq(typeof aObj.ownProperties.arr.value, "object",
'serialized object property "arr" should be a grip');
do_check_eq(typeof aObj.ownProperties.inf, "object",
'serialized object should have property "inf"');
do_check_eq(typeof aObj.ownProperties.inf.value, "object",
'serialized object property "inf" should be a grip');
do_check_eq(typeof aObj.ownProperties.ninf, "object",
'serialized object should have property "ninf"');
do_check_eq(typeof aObj.ownProperties.ninf.value, "object",
'serialized object property "ninf" should be a grip');
do_check_eq(typeof aObj.ownProperties.nan, "object",
'serialized object should have property "nan"');
do_check_eq(typeof aObj.ownProperties.nan.value, "object",
'serialized object property "nan" should be a grip');
do_check_eq(typeof aObj.ownProperties.nzero, "object",
'serialized object should have property "nzero"');
do_check_eq(typeof aObj.ownProperties.nzero.value, "object",
'serialized object property "nzero" should be a grip');
do_check_eq(aObj.prototype.type, "object");
do_check_eq(aObj.ownProperties.num.value, 0);
do_check_eq(aObj.ownProperties.str.value, "foo");
do_check_eq(aObj.ownProperties.bool.value, false);
do_check_eq(aObj.ownProperties.undef.value.type, "undefined");
do_check_eq(aObj.ownProperties.nil.value.type, "null");
do_check_eq(aObj.ownProperties.obj.value.type, "object");
do_check_eq(aObj.ownProperties.obj.value.class, "Object");
do_check_eq(aObj.ownProperties.arr.value.type, "object");
do_check_eq(aObj.ownProperties.arr.value.class, "Array");
do_check_eq(aObj.ownProperties.inf.value.type, "Infinity");
do_check_eq(aObj.ownProperties.ninf.value.type, "-Infinity");
do_check_eq(aObj.ownProperties.nan.value.type, "NaN");
do_check_eq(aObj.ownProperties.nzero.value.type, "-0");
}