diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 7f77c145755a..3ca73b7bae54 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 52d9beae1882..39798ff479e1 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index f9b9939bd87c..91215b76d45e 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 7f77c145755a..3ca73b7bae54 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 0a89820afe88..913b9b78f107 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 03b25a571648..7a926808cdb9 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
- "revision": "7f0af1e164a39efb732c0c341c2a8e51f681d913",
+ "revision": "c3d40600c0090c5ca6ca4427f3a870ff443a109d",
"repo_path": "/integration/gaia-central"
}
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 9284bc57a774..b1d5bf83a546 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index be2109e1a11d..3f59d2f4181d 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 01483d247122..15e68ab6e846 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 1199de03df88..1b149f836deb 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/browser/base/content/highlighter.css b/browser/base/content/highlighter.css
index cb29d4119626..7e61b8224c1d 100644
--- a/browser/base/content/highlighter.css
+++ b/browser/base/content/highlighter.css
@@ -45,6 +45,7 @@ svg|line.box-model-guide-bottom[hidden] {
html|*.highlighter-nodeinfobar-id,
html|*.highlighter-nodeinfobar-classes,
html|*.highlighter-nodeinfobar-pseudo-classes,
+html|*.highlighter-nodeinfobar-dimensions,
html|*.highlighter-nodeinfobar-tagname {
-moz-user-select: text;
-moz-user-focus: normal;
diff --git a/browser/base/content/newtab/page.js b/browser/base/content/newtab/page.js
index 8a81780fd021..b99f76456dc8 100644
--- a/browser/base/content/newtab/page.js
+++ b/browser/base/content/newtab/page.js
@@ -210,7 +210,19 @@ let gPage = {
for (let site of gGrid.sites) {
if (site) {
site.captureIfMissing();
- let {type} = site.link;
+
+ // Record which tile index a directory link was shown
+ let {directoryIndex, type} = site.link;
+ if (directoryIndex !== undefined) {
+ let tileIndex = site.cell.index;
+ // For telemetry, only handle the first 9 links in the first 9 cells
+ if (directoryIndex < 9) {
+ let shownId = "NEWTAB_PAGE_DIRECTORY_LINK" + directoryIndex + "_SHOWN";
+ Services.telemetry.getHistogramById(shownId).add(Math.min(9, tileIndex));
+ }
+ }
+
+ // Aggregate tile impression counts into directory types
if (type in directoryCount) {
directoryCount[type]++;
}
diff --git a/browser/devtools/commandline/test/browser_cmd_appcache_invalid.js b/browser/devtools/commandline/test/browser_cmd_appcache_invalid.js
index 432a57f022ed..a7e58abf0ed4 100644
--- a/browser/devtools/commandline/test/browser_cmd_appcache_invalid.js
+++ b/browser/devtools/commandline/test/browser_cmd_appcache_invalid.js
@@ -12,6 +12,70 @@ function test() {
}
function spawnTest() {
+ let lines = [
+ 'Manifest has a character encoding of ISO-8859-1. Manifests must have the ' +
+ 'utf-8 character encoding.',
+ 'The first line of the manifest must be "CACHE MANIFEST" at line 1.',
+ '"CACHE MANIFEST" is only valid on the first line but was found at line 3.',
+ 'images/sound-icon.png points to a resource that is not available at line 9.',
+ 'images/background.png points to a resource that is not available at line 10.',
+ '/checking.cgi points to a resource that is not available at line 13.',
+ 'Asterisk (*) incorrectly used in the NETWORK section at line 14. If a line ' +
+ 'in the NETWORK section contains only a single asterisk character, then any ' +
+ 'URI not listed in the manifest will be treated as if the URI was listed in ' +
+ 'the NETWORK section. Otherwise such URIs will be treated as unavailable. ' +
+ 'Other uses of the * character are prohibited',
+ '../rel.html points to a resource that is not available at line 17.',
+ '../../rel.html points to a resource that is not available at line 18.',
+ '../../../rel.html points to a resource that is not available at line 19.',
+ '../../../../rel.html points to a resource that is not available at line 20.',
+ '../../../../../rel.html points to a resource that is not available at line 21.',
+ '/../ is not a valid URI prefix at line 22.',
+ '/test.css points to a resource that is not available at line 23.',
+ '/test.js points to a resource that is not available at line 24.',
+ 'test.png points to a resource that is not available at line 25.',
+ '/main/features.js points to a resource that is not available at line 27.',
+ '/main/settings/index.css points to a resource that is not available at line 28.',
+ 'http://example.com/scene.jpg points to a resource that is not available at line 29.',
+ '/section1/blockedbyfallback.html points to a resource that is not available at line 30.',
+ 'http://example.com/images/world.jpg points to a resource that is not available at line 31.',
+ '/section2/blockedbyfallback.html points to a resource that is not available at line 32.',
+ '/main/home points to a resource that is not available at line 34.',
+ 'main/app.js points to a resource that is not available at line 35.',
+ '/settings/home points to a resource that is not available at line 37.',
+ '/settings/app.js points to a resource that is not available at line 38.',
+ 'The file http://sub1.test1.example.com/browser/browser/devtools/' +
+ 'commandline/test/browser_cmd_appcache_invalid_page3.html was modified ' +
+ 'after http://sub1.test1.example.com/browser/browser/devtools/' +
+ 'commandline/test/browser_cmd_appcache_invalid_appcache.appcache. Unless ' +
+ 'the text in the manifest file is changed the cached version will be used ' +
+ 'instead at line 39.',
+ 'browser_cmd_appcache_invalid_page3.html has cache-control set to no-store. ' +
+ 'This will prevent the application cache from storing the file at line 39.',
+ 'http://example.com/logo.png points to a resource that is not available at line 40.',
+ 'http://example.com/check.png points to a resource that is not available at line 41.',
+ 'Spaces in URIs need to be replaced with % at line 42.',
+ 'http://example.com/cr oss.png points to a resource that is not available at line 42.',
+ 'Asterisk (*) incorrectly used in the CACHE section at line 43. If a line ' +
+ 'in the NETWORK section contains only a single asterisk character, then ' +
+ 'any URI not listed in the manifest will be treated as if the URI was ' +
+ 'listed in the NETWORK section. Otherwise such URIs will be treated as ' +
+ 'unavailable. Other uses of the * character are prohibited',
+ 'The SETTINGS section may only contain a single value, "prefer-online" or "fast" at line 47.',
+ 'FALLBACK section line 50 (/section1/ /offline1.html) prevents caching of ' +
+ 'line 30 (/section1/blockedbyfallback.html) in the CACHE section.',
+ '/offline1.html points to a resource that is not available at line 50.',
+ 'FALLBACK section line 51 (/section2/ offline2.html) prevents caching of ' +
+ 'line 32 (/section2/blockedbyfallback.html) in the CACHE section.',
+ 'offline2.html points to a resource that is not available at line 51.',
+ 'Only two URIs separated by spaces are allowed in the FALLBACK section at line 52.',
+ 'Asterisk (*) incorrectly used in the FALLBACK section at line 53. URIs ' +
+ 'in the FALLBACK section simply need to match a prefix of the request URI.',
+ 'offline3.html points to a resource that is not available at line 53.',
+ 'Invalid section name (BLAH) at line 55.',
+ 'Only two URIs separated by spaces are allowed in the FALLBACK section at line 55.'
+ ];
+
let options = yield helpers.openTab(TEST_URI);
info("window open");
@@ -25,7 +89,8 @@ function spawnTest() {
// Pages containing an appcache the notification bar gives options to allow
// or deny permission for the app to save data offline. Let's click Allow.
let notificationID = "offline-app-requested-sub1.test1.example.com";
- let notification = PopupNotifications.getNotification(notificationID, gBrowser.selectedBrowser);
+ let notification =
+ PopupNotifications.getNotification(notificationID, gBrowser.selectedBrowser);
if (notification) {
info("Authorizing offline storage.");
@@ -45,52 +110,7 @@ function spawnTest() {
args: {}
},
exec: {
- output: [
- /Manifest has a character encoding of ISO-8859-1\. Manifests must have the utf-8 character encoding\./,
- /The first line of the manifest must be "CACHE MANIFEST" at line 1\./,
- /"CACHE MANIFEST" is only valid on the first line but was found at line 3\./,
- /images\/sound-icon\.png points to a resource that is not available at line 9\./,
- /images\/background\.png points to a resource that is not available at line 10\./,
- /NETWORK section line 13 \(\/checking\.cgi\) prevents caching of line 13 \(\/checking\.cgi\) in the NETWORK section\./,
- /\/checking\.cgi points to a resource that is not available at line 13\./,
- /Asterisk \(\*\) incorrectly used in the NETWORK section at line 14\. If a line in the NETWORK section contains only a single asterisk character, then any URI not listed in the manifest will be treated as if the URI was listed in the NETWORK section\. Otherwise such URIs will be treated as unavailable\. Other uses of the \* character are prohibited/,
- /\.\.\/rel\.html points to a resource that is not available at line 17\./,
- /\.\.\/\.\.\/rel\.html points to a resource that is not available at line 18\./,
- /\.\.\/\.\.\/\.\.\/rel\.html points to a resource that is not available at line 19\./,
- /\.\.\/\.\.\/\.\.\/\.\.\/rel\.html points to a resource that is not available at line 20\./,
- /\.\.\/\.\.\/\.\.\/\.\.\/\.\.\/rel\.html points to a resource that is not available at line 21\./,
- /\/\.\.\/ is not a valid URI prefix at line 22\./,
- /\/test\.css points to a resource that is not available at line 23\./,
- /\/test\.js points to a resource that is not available at line 24\./,
- /test\.png points to a resource that is not available at line 25\./,
- /\/main\/features\.js points to a resource that is not available at line 27\./,
- /\/main\/settings\/index\.css points to a resource that is not available at line 28\./,
- /http:\/\/example\.com\/scene\.jpg points to a resource that is not available at line 29\./,
- /\/section1\/blockedbyfallback\.html points to a resource that is not available at line 30\./,
- /http:\/\/example\.com\/images\/world\.jpg points to a resource that is not available at line 31\./,
- /\/section2\/blockedbyfallback\.html points to a resource that is not available at line 32\./,
- /\/main\/home points to a resource that is not available at line 34\./,
- /main\/app\.js points to a resource that is not available at line 35\./,
- /\/settings\/home points to a resource that is not available at line 37\./,
- /\/settings\/app\.js points to a resource that is not available at line 38\./,
- /The file http:\/\/sub1\.test1\.example\.com\/browser\/browser\/devtools\/commandline\/test\/browser_cmd_appcache_invalid_page3\.html was modified after http:\/\/sub1\.test1\.example\.com\/browser\/browser\/devtools\/commandline\/test\/browser_cmd_appcache_invalid_appcache\.appcache\. Unless the text in the manifest file is changed the cached version will be used instead at line 39\./,
- /browser_cmd_appcache_invalid_page3\.html has cache-control set to no-store\. This will prevent the application cache from storing the file at line 39\./,
- /http:\/\/example\.com\/logo\.png points to a resource that is not available at line 40\./,
- /http:\/\/example\.com\/check\.png points to a resource that is not available at line 41\./,
- /Spaces in URIs need to be replaced with % at line 42\./,
- /http:\/\/example\.com\/cr oss\.png points to a resource that is not available at line 42\./,
- /Asterisk \(\*\) incorrectly used in the CACHE section at line 43\. If a line in the NETWORK section contains only a single asterisk character, then any URI not listed in the manifest will be treated as if the URI was listed in the NETWORK section\. Otherwise such URIs will be treated as unavailable\. Other uses of the \* character are prohibited/,
- /The SETTINGS section may only contain a single value, "prefer-online" or "fast" at line 47\./,
- /FALLBACK section line 50 \(\/section1\/ \/offline1\.html\) prevents caching of line 30 \(\/section1\/blockedbyfallback\.html\) in the CACHE section\./,
- /\/offline1\.html points to a resource that is not available at line 50\./,
- /FALLBACK section line 51 \(\/section2\/ offline2\.html\) prevents caching of line 32 \(\/section2\/blockedbyfallback\.html\) in the CACHE section\./,
- /offline2\.html points to a resource that is not available at line 51\./,
- /Only two URIs separated by spaces are allowed in the FALLBACK section at line 52\./,
- /Asterisk \(\*\) incorrectly used in the FALLBACK section at line 53\. URIs in the FALLBACK section simply need to match a prefix of the request URI\./,
- /offline3\.html points to a resource that is not available at line 53\./,
- /Invalid section name \(BLAH\) at line 55\./,
- /Only two URIs separated by spaces are allowed in the FALLBACK section at line 55\./
- ]
+ output: lines.map(getRegexForString)
},
},
]);
diff --git a/browser/devtools/commandline/test/head.js b/browser/devtools/commandline/test/head.js
index 602198769ff0..fbe0d1a7997c 100644
--- a/browser/devtools/commandline/test/head.js
+++ b/browser/devtools/commandline/test/head.js
@@ -27,6 +27,20 @@ function whenDelayedStartupFinished(aWindow, aCallback) {
}, "browser-delayed-startup-finished", false);
}
+/**
+ * Creates a regular expression that matches a string. This greatly simplifies
+ * matching and debugging long strings.
+ *
+ * @param {String} text
+ * Text to convert
+ * @return {RegExp}
+ * Regular expression matching text
+ */
+function getRegexForString(str) {
+ str = str.replace(/(\.|\\|\/|\(|\)|\[|\]|\*|\+|\?|\$|\^|\|)/g, "\\$1");
+ return new RegExp(str);
+}
+
/**
* Force GC on shutdown, because it seems that GCLI can outrun the garbage
* collector in some situations, which causes test failures in later tests
diff --git a/browser/devtools/inspector/test/browser_inspector_highlighter.js b/browser/devtools/inspector/test/browser_inspector_highlighter.js
index c2c8401e8003..46016dce8765 100644
--- a/browser/devtools/inspector/test/browser_inspector_highlighter.js
+++ b/browser/devtools/inspector/test/browser_inspector_highlighter.js
@@ -5,106 +5,71 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
let doc;
-let h1;
+let div;
+let rotated;
let inspector;
+let contentViewer;
function createDocument() {
- let div = doc.createElement("div");
- h1 = doc.createElement("h1");
- let p1 = doc.createElement("p");
- let p2 = doc.createElement("p");
- let div2 = doc.createElement("div");
- let p3 = doc.createElement("p");
- doc.title = "Inspector Highlighter Meatballs";
- h1.textContent = "Inspector Tree Selection Test";
- p1.textContent = "This is some example text";
- p2.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
- "elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
- "aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
- "laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
- "dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
- "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
- "proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
- p3.textContent = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
- "elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
- "aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
- "laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
- "dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
- "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
- "proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
- let div3 = doc.createElement("div");
- div3.id = "checkOutThisWickedSpread";
- div3.setAttribute("style", "position: absolute; top: 20px; right: 20px; height: 20px; width: 20px; background-color: yellow; border: 1px dashed black;");
- let p4 = doc.createElement("p");
- p4.setAttribute("style", "font-weight: 200; font-size: 8px; text-align: center;");
- p4.textContent = "Smörgåsbord!";
- div.appendChild(h1);
- div.appendChild(p1);
- div.appendChild(p2);
- div2.appendChild(p3);
- div3.appendChild(p4);
+ div = doc.createElement("div");
+ div.setAttribute("style",
+ "padding:5px; border:7px solid red; margin: 9px; " +
+ "position:absolute; top:30px; left:150px;");
+ let textNode = doc.createTextNode("Gort! Klaatu barada nikto!");
+ rotated = doc.createElement("div");
+ rotated.setAttribute("style",
+ "padding:5px; border:7px solid red; margin: 9px; " +
+ "transform:rotate(45deg); " +
+ "position:absolute; top:30px; left:80px;");
+ div.appendChild(textNode);
doc.body.appendChild(div);
- doc.body.appendChild(div2);
- doc.body.appendChild(div3);
+ doc.body.appendChild(rotated);
openInspector(aInspector => {
inspector = aInspector;
inspector.selection.setNode(div, null);
- inspector.once("inspector-updated", () => {
- inspector.toolbox.highlighterUtils.startPicker().then(testMouseOverH1Highlights);
- });
+ inspector.once("inspector-updated", testMouseOverDivHighlights);
});
}
-function testMouseOverH1Highlights() {
+function testMouseOverDivHighlights() {
+ ok(isHighlighting(), "Highlighter is shown");
+ is(getHighlitNode(), div, "Highlighter's outline correspond to the non-rotated div");
+ testNonTransformedBoxModelDimensionsNoZoom();
+}
+
+function testNonTransformedBoxModelDimensionsNoZoom() {
+ info("Highlighted the non-rotated div");
+ isNodeCorrectlyHighlighted(div, "non-zoomed");
+
+ inspector.toolbox.once("highlighter-ready", testNonTransformedBoxModelDimensionsZoomed);
+ contentViewer = gBrowser.selectedBrowser.docShell.contentViewer
+ .QueryInterface(Ci.nsIMarkupDocumentViewer);
+ contentViewer.fullZoom = 2;
+}
+
+function testNonTransformedBoxModelDimensionsZoomed() {
+ info("Highlighted the zoomed, non-rotated div");
+ isNodeCorrectlyHighlighted(div, "zoomed");
+
+ inspector.toolbox.once("highlighter-ready", testMouseOverRotatedHighlights);
+ contentViewer.fullZoom = 1;
+}
+
+function testMouseOverRotatedHighlights() {
inspector.toolbox.once("highlighter-ready", () => {
ok(isHighlighting(), "Highlighter is shown");
- is(getHighlitNode(), h1, "Highlighter's outline correspond to the selected node");
- testBoxModelDimensions();
+ info("Highlighted the rotated div");
+ isNodeCorrectlyHighlighted(rotated, "rotated");
+
+ executeSoon(finishUp);
});
-
- EventUtils.synthesizeMouse(h1, 2, 2, {type: "mousemove"}, content);
-}
-
-function testBoxModelDimensions() {
- let h1Dims = h1.getBoundingClientRect();
- let h1Width = Math.ceil(h1Dims.width);
- let h1Height = Math.ceil(h1Dims.height);
-
- let outlineDims = getSimpleBorderRect();
- let outlineWidth = Math.ceil(outlineDims.width);
- let outlineHeight = Math.ceil(outlineDims.height);
-
- // Disabled due to bug 716245
- is(outlineWidth, h1Width, "outline width matches dimensions of element (no zoom)");
- is(outlineHeight, h1Height, "outline height matches dimensions of element (no zoom)");
-
- // zoom the page by a factor of 2
- let contentViewer = gBrowser.selectedBrowser.docShell.contentViewer
- .QueryInterface(Ci.nsIMarkupDocumentViewer);
- contentViewer.fullZoom = 2;
-
- // simulate the zoomed dimensions of the div element
- let h1Dims = h1.getBoundingClientRect();
- // There seems to be some very minor differences in the floats, so let's
- // floor the values
- let h1Width = Math.floor(h1Dims.width * contentViewer.fullZoom);
- let h1Height = Math.floor(h1Dims.height * contentViewer.fullZoom);
-
- let outlineDims = getSimpleBorderRect();
- let outlineWidth = Math.floor(outlineDims.width);
- let outlineHeight = Math.floor(outlineDims.height);
-
- is(outlineWidth, h1Width, "outline width matches dimensions of element (zoomed)");
-
- is(outlineHeight, h1Height, "outline height matches dimensions of element (zoomed)");
-
- executeSoon(finishUp);
+ inspector.selection.setNode(rotated);
}
function finishUp() {
inspector.toolbox.highlighterUtils.stopPicker().then(() => {
- doc = h1 = inspector = null;
+ doc = div = rotated = inspector = contentViewer = null;
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.closeToolbox(target);
gBrowser.removeCurrentTab();
diff --git a/browser/devtools/inspector/test/browser_inspector_infobar.js b/browser/devtools/inspector/test/browser_inspector_infobar.js
index 2aabae619ae8..cdc61ea0c8a0 100644
--- a/browser/devtools/inspector/test/browser_inspector_infobar.js
+++ b/browser/devtools/inspector/test/browser_inspector_infobar.js
@@ -17,19 +17,58 @@ function test() {
waitForFocus(setupInfobarTest, content);
}, true);
- let style = "body{width:100%;height: 100%} div {position: absolute;height: 100px;width: 500px}#bottom {bottom: 0px}#vertical {height: 100%}#farbottom{bottom: -200px}";
- let html = "
"
+ let style = "body{width:100%;height: 100%} div {position: absolute;" +
+ "height: 100px;width: 500px}#bottom {bottom: 0px}#vertical {"+
+ "height: 100%}#farbottom{bottom: -200px}";
+ let html = "" +
+ "" +
+ ""
- content.location = "data:text/html," + encodeURIComponent(html);
+ content.location = "data:text/html;charset=utf-8," + encodeURIComponent(html);
function setupInfobarTest() {
nodes = [
- {node: doc.querySelector("#top"), position: "bottom", tag: "DIV", id: "#top", classes: ".class1.class2"},
- {node: doc.querySelector("#vertical"), position: "overlap", tag: "DIV", id: "#vertical", classes: ""},
- {node: doc.querySelector("#bottom"), position: "top", tag: "DIV", id: "#bottom", classes: ""},
- {node: doc.querySelector("body"), position: "overlap", tag: "BODY", id: "", classes: ""},
- {node: doc.querySelector("#farbottom"), position: "top", tag: "DIV", id: "#farbottom", classes: ""},
- ]
+ {
+ node: doc.querySelector("#top"),
+ position: "bottom",
+ tag: "DIV",
+ id: "#top",
+ classes: ".class1.class2",
+ dims: "500 x 100"
+ },
+ {
+ node: doc.querySelector("#vertical"),
+ position: "overlap",
+ tag: "DIV",
+ id: "#vertical",
+ classes: ""
+ // No dims as they will vary between computers
+ },
+ {
+ node: doc.querySelector("#bottom"),
+ position: "top",
+ tag: "DIV",
+ id: "#bottom",
+ classes: "",
+ dims: "500 x 100"
+ },
+ {
+ node: doc.querySelector("body"),
+ position: "overlap",
+ tag: "BODY",
+ id: "",
+ classes: ""
+ // No dims as they will vary between computers
+ },
+ {
+ node: doc.querySelector("#farbottom"),
+ position: "top",
+ tag: "DIV",
+ id: "#farbottom",
+ classes: "",
+ dims: "500 x 100"
+ },
+ ];
for (let i = 0; i < nodes.length; i++) {
ok(nodes[i].node, "node " + i + " found");
@@ -74,16 +113,24 @@ function test() {
let stack = browser.parentNode;
let container = stack.querySelector(".highlighter-nodeinfobar-positioner");
- is(container.getAttribute("position"), nodes[cursor].position, "node " + cursor + ": position matches.");
+ is(container.getAttribute("position"),
+ nodes[cursor].position, "node " + cursor + ": position matches.");
let tagNameLabel = stack.querySelector(".highlighter-nodeinfobar-tagname");
- is(tagNameLabel.textContent, nodes[cursor].tag, "node " + cursor + ": tagName matches.");
+ is(tagNameLabel.textContent, nodes[cursor].tag,
+ "node " + cursor + ": tagName matches.");
let idLabel = stack.querySelector(".highlighter-nodeinfobar-id");
is(idLabel.textContent, nodes[cursor].id, "node " + cursor + ": id matches.");
let classesBox = stack.querySelector(".highlighter-nodeinfobar-classes");
- is(classesBox.textContent, nodes[cursor].classes, "node " + cursor + ": classes match.");
+ is(classesBox.textContent, nodes[cursor].classes,
+ "node " + cursor + ": classes match.");
+
+ if (nodes[cursor].dims) {
+ let dimBox = stack.querySelector(".highlighter-nodeinfobar-dimensions");
+ is(dimBox.textContent, nodes[cursor].dims, "node " + cursor + ": dims match.");
+ }
}
function finishUp() {
diff --git a/browser/devtools/inspector/test/head.js b/browser/devtools/inspector/test/head.js
index e3e3c66b74c7..cf3a10469c18 100644
--- a/browser/devtools/inspector/test/head.js
+++ b/browser/devtools/inspector/test/head.js
@@ -400,7 +400,7 @@ function focusSearchBoxUsingShortcut(panelWin, callback) {
altKey: modifiersAttr.match("alt"),
metaKey: modifiersAttr.match("meta"),
accelKey: modifiersAttr.match("accel")
- }
+ };
let searchBox = panelWin.document.getElementById("inspector-searchbox");
searchBox.addEventListener("focus", function onFocus() {
@@ -425,6 +425,60 @@ function getComputedPropertyValue(aName)
}
}
+function isNodeCorrectlyHighlighted(node, prefix="") {
+ let boxModel = getBoxModelStatus();
+ let helper = new LayoutHelpers(window.content);
+
+ prefix += (prefix ? " " : "") + node.nodeName;
+ prefix += (node.id ? "#" + node.id : "");
+ prefix += (node.classList.length ? "." + [...node.classList].join(".") : "");
+ prefix += " ";
+
+ let quads = helper.getAdjustedQuads(node, "content");
+ let {p1:cp1, p2:cp2, p3:cp3, p4:cp4} = boxModel.content.points;
+ is(cp1.x, quads.p1.x, prefix + "content point 1 x co-ordinate is correct");
+ is(cp1.y, quads.p1.y, prefix + "content point 1 y co-ordinate is correct");
+ is(cp2.x, quads.p2.x, prefix + "content point 2 x co-ordinate is correct");
+ is(cp2.y, quads.p2.y, prefix + "content point 2 y co-ordinate is correct");
+ is(cp3.x, quads.p3.x, prefix + "content point 3 x co-ordinate is correct");
+ is(cp3.y, quads.p3.y, prefix + "content point 3 y co-ordinate is correct");
+ is(cp4.x, quads.p4.x, prefix + "content point 4 x co-ordinate is correct");
+ is(cp4.y, quads.p4.y, prefix + "content point 4 y co-ordinate is correct");
+
+ quads = helper.getAdjustedQuads(node, "padding");
+ let {p1:pp1, p2:pp2, p3:pp3, p4:pp4} = boxModel.padding.points;
+ is(pp1.x, quads.p1.x, prefix + "padding point 1 x co-ordinate is correct");
+ is(pp1.y, quads.p1.y, prefix + "padding point 1 y co-ordinate is correct");
+ is(pp2.x, quads.p2.x, prefix + "padding point 2 x co-ordinate is correct");
+ is(pp2.y, quads.p2.y, prefix + "padding point 2 y co-ordinate is correct");
+ is(pp3.x, quads.p3.x, prefix + "padding point 3 x co-ordinate is correct");
+ is(pp3.y, quads.p3.y, prefix + "padding point 3 y co-ordinate is correct");
+ is(pp4.x, quads.p4.x, prefix + "padding point 4 x co-ordinate is correct");
+ is(pp4.y, quads.p4.y, prefix + "padding point 4 y co-ordinate is correct");
+
+ quads = helper.getAdjustedQuads(node, "border");
+ let {p1:bp1, p2:bp2, p3:bp3, p4:bp4} = boxModel.border.points;
+ is(bp1.x, quads.p1.x, prefix + "border point 1 x co-ordinate is correct");
+ is(bp1.y, quads.p1.y, prefix + "border point 1 y co-ordinate is correct");
+ is(bp2.x, quads.p2.x, prefix + "border point 2 x co-ordinate is correct");
+ is(bp2.y, quads.p2.y, prefix + "border point 2 y co-ordinate is correct");
+ is(bp3.x, quads.p3.x, prefix + "border point 3 x co-ordinate is correct");
+ is(bp3.y, quads.p3.y, prefix + "border point 3 y co-ordinate is correct");
+ is(bp4.x, quads.p4.x, prefix + "border point 4 x co-ordinate is correct");
+ is(bp4.y, quads.p4.y, prefix + "border point 4 y co-ordinate is correct");
+
+ quads = helper.getAdjustedQuads(node, "margin");
+ let {p1:mp1, p2:mp2, p3:mp3, p4:mp4} = boxModel.margin.points;
+ is(mp1.x, quads.p1.x, prefix + "margin point 1 x co-ordinate is correct");
+ is(mp1.y, quads.p1.y, prefix + "margin point 1 y co-ordinate is correct");
+ is(mp2.x, quads.p2.x, prefix + "margin point 2 x co-ordinate is correct");
+ is(mp2.y, quads.p2.y, prefix + "margin point 2 y co-ordinate is correct");
+ is(mp3.x, quads.p3.x, prefix + "margin point 3 x co-ordinate is correct");
+ is(mp3.y, quads.p3.y, prefix + "margin point 3 y co-ordinate is correct");
+ is(mp4.x, quads.p4.x, prefix + "margin point 4 x co-ordinate is correct");
+ is(mp4.y, quads.p4.y, prefix + "margin point 4 y co-ordinate is correct");
+}
+
function getContainerForRawNode(markupView, rawNode)
{
let front = markupView.walker.frontForRawNode(rawNode);
diff --git a/browser/devtools/shared/AppCacheUtils.jsm b/browser/devtools/shared/AppCacheUtils.jsm
index 98a68e71b4fa..2b6d066dc64c 100644
--- a/browser/devtools/shared/AppCacheUtils.jsm
+++ b/browser/devtools/shared/AppCacheUtils.jsm
@@ -118,7 +118,8 @@ AppCacheUtils.prototype = {
for (let neturi of parsed.uris) {
if (neturi.section == "NETWORK") {
for (let parsedUri of parsed.uris) {
- if (parsedUri.uri.startsWith(neturi.uri)) {
+ if (parsedUri.section !== "NETWORK" &&
+ parsedUri.uri.startsWith(neturi.uri)) {
this._addError(neturi.line, "networkBlocksURI", neturi.line,
neturi.original, parsedUri.line, parsedUri.original,
parsedUri.section);
@@ -164,7 +165,7 @@ AppCacheUtils.prototype = {
this._addError(parsedUri.line, "cacheControlNoStore",
parsedUri.original, parsedUri.line);
}
- } else {
+ } else if (parsedUri.original !== "*") {
this._addError(parsedUri.line, "notAvailable",
parsedUri.original, parsedUri.line);
}
@@ -182,7 +183,6 @@ AppCacheUtils.prototype = {
let inputStream = Cc["@mozilla.org/scriptableinputstream;1"]
.createInstance(Ci.nsIScriptableInputStream);
let deferred = promise.defer();
- let channelCharset = "";
let buffer = "";
let channel = Services.io.newChannel(uri, null, null);
@@ -203,7 +203,7 @@ AppCacheUtils.prototype = {
},
onStopRequest: function onStartRequest(request, context, statusCode) {
- if (statusCode == 0) {
+ if (statusCode === 0) {
request.QueryInterface(Ci.nsIHttpChannel);
let result = {
@@ -279,7 +279,7 @@ AppCacheUtils.prototype = {
}
});
- if (entries.length == 0) {
+ if (entries.length === 0) {
throw new Error(l10n.GetStringFromName("noResults"));
}
return entries;
@@ -320,17 +320,23 @@ AppCacheUtils.prototype = {
_getManifestURI: function ACU__getManifestURI() {
let deferred = promise.defer();
- let getURI = node => {
+ let getURI = () => {
let htmlNode = this.doc.querySelector("html[manifest]");
if (htmlNode) {
let pageUri = this.doc.location ? this.doc.location.href : this.uri;
let origin = pageUri.substr(0, pageUri.lastIndexOf("/") + 1);
- return origin + htmlNode.getAttribute("manifest");
+ let manifestURI = htmlNode.getAttribute("manifest");
+
+ if (manifestURI.startsWith("/")) {
+ manifestURI = manifestURI.substr(1);
+ }
+
+ return origin + manifestURI;
}
};
if (this.doc) {
- let uri = getURI(this.doc);
+ let uri = getURI();
return promise.resolve(uri);
} else {
this._getURIInfo(this.uri).then(uriInfo => {
@@ -338,7 +344,7 @@ AppCacheUtils.prototype = {
let html = uriInfo.text;
let parser = _DOMParser;
this.doc = parser.parseFromString(html, "text/html");
- let uri = getURI(this.doc);
+ let uri = getURI();
deferred.resolve(uri);
} else {
this.errors.push({
@@ -394,10 +400,10 @@ ManifestParser.prototype = {
this.currSection = "CACHE";
for (let i = 0; i < lines.length; i++) {
- let text = this.text = lines[i].replace(/^\s+|\s+$/g);
+ let text = this.text = lines[i].trim();
this.currentLine = i + 1;
- if (i == 0 && text != "CACHE MANIFEST") {
+ if (i === 0 && text !== "CACHE MANIFEST") {
this._addError(1, "firstLineMustBeCacheManifest", 1);
}
@@ -453,7 +459,7 @@ ManifestParser.prototype = {
if (/\s/.test(text)) {
this._addError(this.currentLine, "escapeSpaces", this.currentLine);
- text = text.replace(/\s/g, "%20")
+ text = text.replace(/\s/g, "%20");
}
if (text[0] == "/") {
@@ -506,7 +512,7 @@ ManifestParser.prototype = {
if (/\s/.test(namespace)) {
this._addError(this.currentLine, "escapeSpaces", this.currentLine);
- namespace = namespace.replace(/\s/g, "%20")
+ namespace = namespace.replace(/\s/g, "%20");
}
if (namespace.substr(0, 4) == "/../") {
diff --git a/browser/devtools/styleeditor/StyleEditorUI.jsm b/browser/devtools/styleeditor/StyleEditorUI.jsm
index 9ad06fb50939..df28eea64c74 100644
--- a/browser/devtools/styleeditor/StyleEditorUI.jsm
+++ b/browser/devtools/styleeditor/StyleEditorUI.jsm
@@ -64,7 +64,7 @@ function StyleEditorUI(debuggee, target, panelDoc) {
this.selectedEditor = null;
this.savedLocations = {};
- this._updateContextMenu = this._updateContextMenu.bind(this);
+ this._updateOptionsMenu = this._updateOptionsMenu.bind(this);
this._onStyleSheetCreated = this._onStyleSheetCreated.bind(this);
this._onNewDocument = this._onNewDocument.bind(this);
this._onMediaPrefChanged = this._onMediaPrefChanged.bind(this);
@@ -142,36 +142,26 @@ StyleEditorUI.prototype = {
this._importFromFile(this._mockImportFile || null, this._window);
}.bind(this));
- this._contextMenu = this._panelDoc.getElementById("sidebar-context");
- this._contextMenu.addEventListener("popupshowing",
- this._updateContextMenu);
+ this._optionsMenu = this._panelDoc.getElementById("style-editor-options-popup");
+ this._optionsMenu.addEventListener("popupshowing",
+ this._updateOptionsMenu);
- this._sourcesItem = this._panelDoc.getElementById("context-origsources");
+ this._sourcesItem = this._panelDoc.getElementById("options-origsources");
this._sourcesItem.addEventListener("command",
this._toggleOrigSources);
- this._mediaItem = this._panelDoc.getElementById("context-show-media");
+ this._mediaItem = this._panelDoc.getElementById("options-show-media");
this._mediaItem.addEventListener("command",
this._toggleMediaSidebar);
},
/**
- * Update text of context menu option to reflect current preference
- * settings
+ * Update options menu items to reflect current preference settings.
*/
- _updateContextMenu: function() {
- let sourceString = "showOriginalSources";
- if (Services.prefs.getBoolPref(PREF_ORIG_SOURCES)) {
- sourceString = "showCSSSources";
- }
- this._sourcesItem.setAttribute("label", _(sourceString + ".label"));
- this._sourcesItem.setAttribute("accesskey", _(sourceString + ".accesskey"));
-
- let mediaString = "showMediaSidebar"
- if (Services.prefs.getBoolPref(PREF_MEDIA_SIDEBAR)) {
- mediaString = "hideMediaSidebar";
- }
- this._mediaItem.setAttribute("label", _(mediaString + ".label"));
- this._mediaItem.setAttribute("accesskey", _(mediaString + ".accesskey"));
+ _updateOptionsMenu: function() {
+ this._sourcesItem.setAttribute("checked",
+ Services.prefs.getBoolPref(PREF_ORIG_SOURCES));
+ this._mediaItem.setAttribute("checked",
+ Services.prefs.getBoolPref(PREF_MEDIA_SIDEBAR));
},
/**
@@ -771,6 +761,9 @@ StyleEditorUI.prototype = {
destroy: function() {
this._clearStyleSheetEditors();
+ this._optionsMenu.removeEventListener("popupshowing",
+ this._updateOptionsMenu);
+
this._prefObserver.off(PREF_ORIG_SOURCES, this._onNewDocument);
this._prefObserver.off(PREF_MEDIA_SIDEBAR, this._onMediaPrefChanged);
this._prefObserver.destroy();
diff --git a/browser/devtools/styleeditor/styleeditor.css b/browser/devtools/styleeditor/styleeditor.css
index 3574da0b0e4f..e8de73c3384b 100644
--- a/browser/devtools/styleeditor/styleeditor.css
+++ b/browser/devtools/styleeditor/styleeditor.css
@@ -15,6 +15,10 @@ li.error > .stylesheet-info > .stylesheet-more > .stylesheet-error-message {
display: block;
}
+.devtools-toolbar > spacer {
+ -moz-box-flex: 1;
+}
+
.splitview-nav > li,
.stylesheet-info,
.stylesheet-more {
diff --git a/browser/devtools/styleeditor/styleeditor.xul b/browser/devtools/styleeditor/styleeditor.xul
index 5fea157fd3a7..0e59e59dd00b 100644
--- a/browser/devtools/styleeditor/styleeditor.xul
+++ b/browser/devtools/styleeditor/styleeditor.xul
@@ -61,9 +61,16 @@
key="key_gotoLine"
command="cmd_gotoLine"/>
-