From 784a68a7a2f2ed8ebd002b01fdd8d23f31e1a571 Mon Sep 17 00:00:00 2001 From: Tim Nguyen Date: Wed, 11 Jun 2014 10:50:00 -0400 Subject: [PATCH 01/23] Bug 963002 - Adjust height of panel subview footers. r=Gijs --- .../themes/shared/customizableui/panelUIOverlay.inc.css | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/browser/themes/shared/customizableui/panelUIOverlay.inc.css b/browser/themes/shared/customizableui/panelUIOverlay.inc.css index 393cc4d3b4f..829166b3236 100644 --- a/browser/themes/shared/customizableui/panelUIOverlay.inc.css +++ b/browser/themes/shared/customizableui/panelUIOverlay.inc.css @@ -139,7 +139,9 @@ panelmultiview[nosubviews=true] > .panel-viewcontainer > .panel-viewstack > .pan .panel-subview-header, .subviewbutton.panel-subview-footer { - padding: 12px; + box-sizing: border-box; + min-height: 41px; + padding: 11px 12px; } .panel-subview-header { @@ -490,8 +492,9 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton { #PanelUI-customize, #PanelUI-quit { margin: 0; - padding: 10px 0; - min-height: 2em; + padding: 11px 0; + box-sizing: border-box; + min-height: 40px; -moz-appearance: none; box-shadow: none; border: none; From 53cdc80b44be272c77d2b267decb5f6770e3e1db Mon Sep 17 00:00:00 2001 From: Jordan Santell Date: Wed, 11 Jun 2014 14:27:00 -0400 Subject: [PATCH 02/23] Bug 994257 - Web Audio Editor now supports both landscape and portrait host views. r=vp --- .../webaudioeditor/webaudioeditor.xul | 6 ++-- .../shared/devtools/webaudioeditor.inc.css | 33 +++++++++++++++---- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/browser/devtools/webaudioeditor/webaudioeditor.xul b/browser/devtools/webaudioeditor/webaudioeditor.xul index fca4fcc9365..30e224b4c59 100644 --- a/browser/devtools/webaudioeditor/webaudioeditor.xul +++ b/browser/devtools/webaudioeditor/webaudioeditor.xul @@ -56,9 +56,11 @@ tabindex="0"/> - + - + Date: Wed, 11 Jun 2014 10:58:00 -0400 Subject: [PATCH 03/23] Bug 1007913 - SVG in web audio editor should always be full size. r=vp --- browser/devtools/webaudioeditor/webaudioeditor.xul | 2 +- browser/themes/shared/devtools/webaudioeditor.inc.css | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/browser/devtools/webaudioeditor/webaudioeditor.xul b/browser/devtools/webaudioeditor/webaudioeditor.xul index 30e224b4c59..6522d8bfb1d 100644 --- a/browser/devtools/webaudioeditor/webaudioeditor.xul +++ b/browser/devtools/webaudioeditor/webaudioeditor.xul @@ -62,7 +62,7 @@ - diff --git a/browser/themes/shared/devtools/webaudioeditor.inc.css b/browser/themes/shared/devtools/webaudioeditor.inc.css index 86c07990f79..23edc8143ef 100644 --- a/browser/themes/shared/devtools/webaudioeditor.inc.css +++ b/browser/themes/shared/devtools/webaudioeditor.inc.css @@ -40,8 +40,8 @@ /* Context Graph */ svg { - position: fixed; overflow: hidden; + -moz-box-flex: 1; } /* Edges in graph */ @@ -170,4 +170,3 @@ text { margin-right: 0px !important; } } - From d866bf7100c0ae8f9572a82a2f0bdc147b179033 Mon Sep 17 00:00:00 2001 From: Hernan Rodriguez Colmeiro Date: Wed, 11 Jun 2014 07:39:00 -0400 Subject: [PATCH 04/23] Bug 1020245 - Call openPreferences from utilityOverlay.js. r=jaws --- .../preferences/in-content/preferences.js | 6 +++-- .../preferences/in-content/tests/browser.ini | 1 + ...g1020245_openPreferences_to_paneContent.js | 25 +++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 browser/components/preferences/in-content/tests/browser_bug1020245_openPreferences_to_paneContent.js diff --git a/browser/components/preferences/in-content/preferences.js b/browser/components/preferences/in-content/preferences.js index 2f61627c641..efc377f5984 100644 --- a/browser/components/preferences/in-content/preferences.js +++ b/browser/components/preferences/in-content/preferences.js @@ -3,7 +3,7 @@ - You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; - + const Cc = Components.classes; const Ci = Components.interfaces; const Cu = Components.utils; @@ -42,7 +42,9 @@ function init_all() { this.removeAttribute("keyboard-navigation"); }); - gotoPref("paneGeneral"); + if (document.getElementById("category-general").selected) { + gotoPref("paneGeneral"); + } } function selectCategory(name) { diff --git a/browser/components/preferences/in-content/tests/browser.ini b/browser/components/preferences/in-content/tests/browser.ini index dc2b7142bc6..a0d6b5b6d74 100644 --- a/browser/components/preferences/in-content/tests/browser.ini +++ b/browser/components/preferences/in-content/tests/browser.ini @@ -6,6 +6,7 @@ support-files = [browser_advanced_update.js] [browser_bug410900.js] [browser_bug731866.js] +[browser_bug1020245_openPreferences_to_paneContent.js] [browser_bug795764_cachedisabled.js] [browser_connection.js] [browser_connection_bug388287.js] diff --git a/browser/components/preferences/in-content/tests/browser_bug1020245_openPreferences_to_paneContent.js b/browser/components/preferences/in-content/tests/browser_bug1020245_openPreferences_to_paneContent.js new file mode 100644 index 00000000000..d53296ea3be --- /dev/null +++ b/browser/components/preferences/in-content/tests/browser_bug1020245_openPreferences_to_paneContent.js @@ -0,0 +1,25 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +add_task(function test() { + waitForExplicitFinish(); + let deferred = Promise.defer(); + gBrowser.selectedTab = gBrowser.addTab("about:blank"); + openPreferences("paneContent"); + let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab); + + newTabBrowser.addEventListener("Initialized", function PrefInit() { + newTabBrowser.removeEventListener("Initialized", PrefInit, true); + newTabBrowser.contentWindow.addEventListener("load", function prefLoad() { + newTabBrowser.contentWindow.removeEventListener("load", prefLoad); + let sel = gBrowser.contentWindow.history.state; + is(sel, "paneContent", "Content pane was selected"); + deferred.resolve(); + gBrowser.removeCurrentTab(); + }); + }, true); + + yield deferred.promise; + + finish(); +}); From c7dd6a9d52e2e3675921a6e3a8b46a81153f3ddb Mon Sep 17 00:00:00 2001 From: Richard Marti Date: Thu, 5 Jun 2014 19:43:01 +0200 Subject: [PATCH 05/23] Bug 1021146 - In-content prefs: Remove the border below Popup Policy. r=jaws --- browser/themes/osx/preferences/in-content/preferences.css | 8 ++++++++ browser/themes/osx/preferences/preferences.css | 4 +--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/browser/themes/osx/preferences/in-content/preferences.css b/browser/themes/osx/preferences/in-content/preferences.css index 0fddc85e50a..44bd312af6f 100644 --- a/browser/themes/osx/preferences/in-content/preferences.css +++ b/browser/themes/osx/preferences/in-content/preferences.css @@ -86,3 +86,11 @@ description { font-size: 1.25rem; line-height: 22px; } + +#popupPolicyRow { + /* Override styles from + browser/themes/osx/preferences/preferences.css */ + margin-bottom: 0 !important; + padding-bottom: 0 !important; + border-bottom: none; +} diff --git a/browser/themes/osx/preferences/preferences.css b/browser/themes/osx/preferences/preferences.css index 4554be0c694..38e73d503cf 100644 --- a/browser/themes/osx/preferences/preferences.css +++ b/browser/themes/osx/preferences/preferences.css @@ -134,9 +134,7 @@ caption { -moz-box-align: center; } -#popupPolicyRow, -#enableSoftwareInstallRow, -#enableImagesRow { +#popupPolicyRow { margin-bottom: 4px !important; padding-bottom: 4px !important; border-bottom: 1px solid #ccc; From a0de5cba51b2faa12b4e259409abdddf222ec974 Mon Sep 17 00:00:00 2001 From: Jim Chen Date: Tue, 10 Jun 2014 12:46:00 -0400 Subject: [PATCH 06/23] Bug 1022769 - Use PersistentRooted to root NativeJSContainer objects. r=jonco --- widget/android/NativeJSContainer.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/widget/android/NativeJSContainer.cpp b/widget/android/NativeJSContainer.cpp index bd598e4b9f9..c41b81c2c2d 100644 --- a/widget/android/NativeJSContainer.cpp +++ b/widget/android/NativeJSContainer.cpp @@ -133,7 +133,7 @@ public: return nullptr; } JSContext* const cx = container->mThreadContext; - JS::RootedObject object(cx, container->mJSObject); + JS::RootedObject object(cx, *container->mJSObject); MOZ_ASSERT(object); JSAutoStructuredCloneBuffer buffer; @@ -179,9 +179,9 @@ public: const jint index = env->GetIntField(object, jObjectIndex); if (index < 0) { // -1 for index field means it's the root object of the container - return container->mJSObject; + return *container->mJSObject; } - return container->mRootedObjects[index]; + return *container->mRootedObjects[index]; } static jobject CreateObjectInstance(JNIEnv* env, jobject object, @@ -197,7 +197,8 @@ public: return nullptr; } size_t newIndex = container->mRootedObjects.length(); - if (!container->mRootedObjects.append(jsObject)) { + PersistentObjectPtr rootedJSObject(new PersistentObject(cx, jsObject)); + if (!container->mRootedObjects.append(Move(rootedJSObject))) { AndroidBridge::ThrowException(env, "java/lang/OutOfMemoryError", "Cannot allocate object"); return nullptr; @@ -231,7 +232,7 @@ public: MOZ_ASSERT(mBuffer.data()); MOZ_ALWAYS_TRUE(mBuffer.read(mThreadContext, &value)); if (value.isObject()) { - mJSObject = &value.toObject(); + mJSObject = new PersistentObject(mThreadContext, &value.toObject()); } if (!mJSObject) { AndroidBridge::ThrowException(env, @@ -278,22 +279,25 @@ private: return newObject; } + typedef JS::PersistentRooted PersistentObject; + typedef ScopedDeletePtr PersistentObjectPtr; + // Thread that the object is valid on PRThread* mThread; // Context that the object is valid in JSContext* mThreadContext; // Deserialized object, or nullptr if object is in serialized form - JS::Heap mJSObject; + PersistentObjectPtr mJSObject; // Serialized object, or empty if object is in deserialized form JSAutoStructuredCloneBuffer mBuffer; // Objects derived from mJSObject - Vector, 4> mRootedObjects; + Vector mRootedObjects; // Create a new container containing the given deserialized object NativeJSContainer(JSContext* cx, JS::HandleObject object) : mThread(PR_GetCurrentThread()) , mThreadContext(cx) - , mJSObject(object) + , mJSObject(new PersistentObject(cx, object)) { } @@ -301,6 +305,7 @@ private: NativeJSContainer(JSContext* cx, JSAutoStructuredCloneBuffer&& buffer) : mThread(PR_GetCurrentThread()) , mThreadContext(cx) + , mJSObject(nullptr) , mBuffer(Forward(buffer)) { } From 9db1b68c656ed69399175f2659c41207ef06b986 Mon Sep 17 00:00:00 2001 From: Gabriel Luong Date: Wed, 11 Jun 2014 08:54:00 -0400 Subject: [PATCH 07/23] Bug 1023923 - Remove the Firefox string from InjectManual l10n string. r=jwalker --- .../en-US/chrome/browser/devtools/gclicommands.properties | 2 +- toolkit/devtools/gcli/commands/inject.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties b/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties index 66aa8350a71..9df5639c7b6 100644 --- a/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties +++ b/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties @@ -1396,7 +1396,7 @@ mediaResetDesc=Stop emulating a CSS media type # injectFailed) These strings describe the 'inject' commands and all available # parameters. injectDesc=Inject common libraries into the page -injectManual=Inject common libraries into the content of the page which can also be accessed from the Firefox console. +injectManual2=Inject common libraries into the content of the page which can also be accessed from the console. injectLibraryDesc=Select the library to inject or enter a valid script URI to inject injectLoaded=%1$S loaded injectFailed=Failed to load %1$S - Invalid URI diff --git a/toolkit/devtools/gcli/commands/inject.js b/toolkit/devtools/gcli/commands/inject.js index 7939677eed9..20a49ad4940 100644 --- a/toolkit/devtools/gcli/commands/inject.js +++ b/toolkit/devtools/gcli/commands/inject.js @@ -12,7 +12,7 @@ exports.items = [ { name: "inject", description: gcli.lookup("injectDesc"), - manual: gcli.lookup("injectManual"), + manual: gcli.lookup("injectManual2"), params: [{ name: 'library', type: { From 0a5f0c5c2f1ac60740131b43b88d38528218bc77 Mon Sep 17 00:00:00 2001 From: Sami Jaktholm Date: Thu, 12 Jun 2014 06:02:00 -0400 Subject: [PATCH 08/23] Bug 1017515 - Add copy color item to context menu of CSS rule and computed views. r=pbrosset --- .../shared/test/browser_outputparser.js | 8 +- browser/devtools/shared/widgets/Tooltip.js | 1 + .../devtools/styleinspector/computed-view.js | 52 +++++++ browser/devtools/styleinspector/rule-view.js | 49 ++++++ .../devtools/styleinspector/test/browser.ini | 2 + ...yleinspector_context-menu-copy-color_01.js | 139 ++++++++++++++++++ ...yleinspector_context-menu-copy-color_02.js | 99 +++++++++++++ .../browser_styleinspector_output-parser.js | 16 +- toolkit/devtools/output-parser.js | 36 ++++- .../global/devtools/styleinspector.properties | 8 + 10 files changed, 394 insertions(+), 16 deletions(-) create mode 100644 browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-color_01.js create mode 100644 browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-color_02.js diff --git a/browser/devtools/shared/test/browser_outputparser.js b/browser/devtools/shared/test/browser_outputparser.js index ab34bf14d7d..cc67178b917 100644 --- a/browser/devtools/shared/test/browser_outputparser.js +++ b/browser/devtools/shared/test/browser_outputparser.js @@ -37,7 +37,7 @@ function testParseCssProperty() { target.appendChild(frag); is(target.innerHTML, - '1px solid #F00', + '1px solid #F00', "CSS property correctly parsed"); target.innerHTML = ""; @@ -48,8 +48,8 @@ function testParseCssProperty() { }); target.appendChild(frag); is(target.innerHTML, - 'linear-gradient(to right, #F60 10%, ' + - '#000)', + 'linear-gradient(to right, #F60 10%, ' + + '#000)', "Gradient CSS property correctly parsed"); target.innerHTML = ""; @@ -69,7 +69,7 @@ function testParseHTMLAttribute() { ok(target, "captain, we have the div"); target.appendChild(frag); - let expected = 'color:#F00; font-size: 12px; ' + + let expected = 'color:#F00; font-size: 12px; ' + 'background-image: url(\'chrome://branding/content/about-logo.png\')'; diff --git a/browser/devtools/shared/widgets/Tooltip.js b/browser/devtools/shared/widgets/Tooltip.js index e5d2983c2ef..5812698c4f5 100644 --- a/browser/devtools/shared/widgets/Tooltip.js +++ b/browser/devtools/shared/widgets/Tooltip.js @@ -1011,6 +1011,7 @@ SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.pr _selectColor: function(color) { if (this.activeSwatch) { this.activeSwatch.style.backgroundColor = color; + this.activeSwatch.parentNode.dataset.color = color; this.currentSwatchColor.textContent = color; this.preview(color); } diff --git a/browser/devtools/styleinspector/computed-view.js b/browser/devtools/styleinspector/computed-view.js index d3960669820..3010008eba7 100644 --- a/browser/devtools/styleinspector/computed-view.js +++ b/browser/devtools/styleinspector/computed-view.js @@ -149,6 +149,7 @@ function CssHtmlTree(aStyleInspector, aPageStyle) this._onSelectAll = this._onSelectAll.bind(this); this._onClick = this._onClick.bind(this); this._onCopy = this._onCopy.bind(this); + this._onCopyColor = this._onCopyColor.bind(this); this.styleDocument.addEventListener("copy", this._onCopy); this.styleDocument.addEventListener("mousedown", this.focusWindow); @@ -584,6 +585,13 @@ CssHtmlTree.prototype = { command: this._onCopy }); + // Copy color + this.menuitemCopyColor = createMenuItem(this._contextmenu, { + label: "ruleView.contextmenu.copyColor", + accesskey: "ruleView.contextmenu.copyColor.accessKey", + command: this._onCopyColor + }); + // Show Original Sources this.menuitemSources= createMenuItem(this._contextmenu, { label: "ruleView.contextmenu.showOrigSources", @@ -619,6 +627,39 @@ CssHtmlTree.prototype = { let accessKey = label + ".accessKey"; this.menuitemSources.setAttribute("accesskey", CssHtmlTree.l10n(accessKey)); + + this.menuitemCopyColor.hidden = !this._isColorPopup(); + }, + + /** + * A helper that determines if the popup was opened with a click to a color + * value and saves the color to this._colorToCopy. + * + * @return {Boolean} + * true if click on color opened the popup, false otherwise. + */ + _isColorPopup: function () { + this._colorToCopy = ""; + + let trigger = this.popupNode; + if (!trigger) { + return false; + } + + let container = (trigger.nodeType == trigger.TEXT_NODE) ? + trigger.parentElement : trigger; + + let isColorNode = el => el.dataset && "color" in el.dataset; + + while (!isColorNode(container)) { + container = container.parentNode; + if (!container) { + return false; + } + } + + this._colorToCopy = container.dataset["color"]; + return true; }, /** @@ -626,6 +667,7 @@ CssHtmlTree.prototype = { */ _onContextMenu: function(event) { try { + this.popupNode = event.explicitOriginalTarget; this.styleDocument.defaultView.focus(); this._contextmenu.openPopupAtScreen(event.screenX, event.screenY, true); } catch(e) { @@ -660,6 +702,10 @@ CssHtmlTree.prototype = { } }, + _onCopyColor: function() { + clipboardHelper.copyString(this._colorToCopy, this.styleDocument); + }, + /** * Copy selected text. * @@ -751,12 +797,18 @@ CssHtmlTree.prototype = { this.menuitemSelectAll.removeEventListener("command", this._onSelectAll); this.menuitemSelectAll = null; + // Destroy Copy Color menuitem. + this.menuitemCopyColor.removeEventListener("command", this._onCopyColor); + this.menuitemCopyColor = null; + // Destroy the context menu. this._contextmenu.removeEventListener("popupshowing", this._contextMenuUpdate); this._contextmenu.parentNode.removeChild(this._contextmenu); this._contextmenu = null; } + this.popupNode = null; + this.tooltip.stopTogglingOnHover(this.propertyContainer); this.tooltip.destroy(); diff --git a/browser/devtools/styleinspector/rule-view.js b/browser/devtools/styleinspector/rule-view.js index b5c9341f5ab..3c9137f7aad 100644 --- a/browser/devtools/styleinspector/rule-view.js +++ b/browser/devtools/styleinspector/rule-view.js @@ -1079,6 +1079,7 @@ function CssRuleView(aInspector, aDoc, aStore, aPageStyle) { this._contextMenuUpdate = this._contextMenuUpdate.bind(this); this._onSelectAll = this._onSelectAll.bind(this); this._onCopy = this._onCopy.bind(this); + this._onCopyColor = this._onCopyColor.bind(this); this._onToggleOrigSources = this._onToggleOrigSources.bind(this); this.element.addEventListener("copy", this._onCopy); @@ -1138,6 +1139,11 @@ CssRuleView.prototype = { accesskey: "ruleView.contextmenu.copy.accessKey", command: this._onCopy }); + this.menuitemCopyColor = createMenuItem(this._contextmenu, { + label: "ruleView.contextmenu.copyColor", + accesskey: "ruleView.contextmenu.copyColor.accessKey", + command: this._onCopyColor + }); this.menuitemSources= createMenuItem(this._contextmenu, { label: "ruleView.contextmenu.showOrigSources", accesskey: "ruleView.contextmenu.showOrigSources.accessKey", @@ -1261,6 +1267,7 @@ CssRuleView.prototype = { copy = false; } + this.menuitemCopyColor.hidden = !this._isColorPopup(); this.menuitemCopy.disabled = !copy; let label = "ruleView.contextmenu.showOrigSources"; @@ -1275,6 +1282,37 @@ CssRuleView.prototype = { _strings.GetStringFromName(accessKey)); }, + /** + * A helper that determines if the popup was opened with a click to a color + * value and saves the color to this._colorToCopy. + * + * @return {Boolean} + * true if click on color opened the popup, false otherwise. + */ + _isColorPopup: function () { + this._colorToCopy = ""; + + let trigger = this.doc.popupNode; + if (!trigger) { + return false; + } + + let container = (trigger.nodeType == trigger.TEXT_NODE) ? + trigger.parentElement : trigger; + + let isColorNode = el => el.dataset && "color" in el.dataset; + + while (!isColorNode(container)) { + container = container.parentNode; + if (!container) { + return false; + } + } + + this._colorToCopy = container.dataset["color"]; + return true; + }, + /** * Select all text. */ @@ -1327,6 +1365,13 @@ CssRuleView.prototype = { } }, + /** + * Copy the most recently selected color value to clipboard. + */ + _onCopyColor: function() { + clipboardHelper.copyString(this._colorToCopy, this.styleDocument); + }, + /** * Toggle the original sources pref. */ @@ -1400,6 +1445,10 @@ CssRuleView.prototype = { this.menuitemCopy.removeEventListener("command", this._onCopy); this.menuitemCopy = null; + // Destroy Copy Color menuitem. + this.menuitemCopyColor.removeEventListener("command", this._onCopyColor); + this.menuitemCopyColor = null; + this.menuitemSources.removeEventListener("command", this._onToggleOrigSources); this.menuitemSources = null; diff --git a/browser/devtools/styleinspector/test/browser.ini b/browser/devtools/styleinspector/test/browser.ini index 9026c165fef..0037c7bfe03 100644 --- a/browser/devtools/styleinspector/test/browser.ini +++ b/browser/devtools/styleinspector/test/browser.ini @@ -87,6 +87,8 @@ skip-if = os == "win" && debug # bug 963492 [browser_ruleview_user-agent-styles.js] [browser_ruleview_user-agent-styles-uneditable.js] [browser_ruleview_user-property-reset.js] +[browser_styleinspector_context-menu-copy-color_01.js] +[browser_styleinspector_context-menu-copy-color_02.js] [browser_styleinspector_csslogic-content-stylesheets.js] [browser_styleinspector_csslogic-inherited-properties.js] [browser_styleinspector_csslogic-specificity.js] diff --git a/browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-color_01.js b/browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-color_01.js new file mode 100644 index 00000000000..52f7eb75db0 --- /dev/null +++ b/browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-color_01.js @@ -0,0 +1,139 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test "Copy color" item of the context menu #1: Test _isColorPopup. + +const TEST_COLOR = "#123ABC"; +const COLOR_SELECTOR = "span[data-color]"; + +let test = asyncTest(function* () { + const TEST_DOC = ' \ + \ +
\ + Test "Copy color" context menu option \ +
\ + \ + '; + + const TEST_CASES = [ + { + viewName: "RuleView", + initializer: openRuleView + }, + { + viewName: "ComputedView", + initializer: openComputedView + } + ]; + + yield addTab("data:text/html;charset=utf8," + encodeURIComponent(TEST_DOC)); + + for (let test of TEST_CASES) { + yield testView(test); + } +}); + +function* testView({viewName, initializer}) { + info("Testing " + viewName); + + let {inspector, view} = yield initializer(); + yield selectNode("div", inspector); + + testIsColorValueNode(view); + testIsColorPopupOnAllNodes(view); + yield clearCurrentNodeSelection(inspector); +} + +/** + * A function testing that isColorValueNode correctly detects nodes part of + * color values. + */ +function testIsColorValueNode(view) { + info("Testing that child nodes of color nodes are detected."); + let root = rootElement(view); + let colorNode = root.querySelector(COLOR_SELECTOR); + + ok(colorNode, "Color node found"); + for (let node of iterateNodes(colorNode)) { + ok(isColorValueNode(node), "Node is part of color value."); + } +} + +/** + * A function testing that _isColorPopup returns a correct value for all nodes + * in the view. + */ +function testIsColorPopupOnAllNodes(view) { + let root = rootElement(view); + for (let node of iterateNodes(root)) { + testIsColorPopupOnNode(view, node); + } +} + +/** + * Test result of _isColorPopup with given node. + * @param object view + * A CSSRuleView or CssHtmlTree instance. + * @param Node node + * A node to check. + */ +function testIsColorPopupOnNode(view, node) { + info("Testing node " + node); + if (view.doc) { + view.doc.popupNode = node; + } + else { + view.popupNode = node; + } + view._colorToCopy = ""; + + let result = view._isColorPopup(); + let correct = isColorValueNode(node); + + is(result, correct, "_isColorPopup returned the expected value " + correct); + is(view._colorToCopy, (correct) ? TEST_COLOR : "", + "_colorToCopy was set to the expected value"); +} + +/** + * Check if a node is part of color value i.e. it has parent with a 'data-color' + * attribute. + */ +function isColorValueNode(node) { + let container = (node.nodeType == node.TEXT_NODE) ? + node.parentElement : node; + + let isColorNode = el => el.dataset && "color" in el.dataset; + + while (!isColorNode(container)) { + container = container.parentNode; + if (!container) { + info("No color. Node is not part of color value."); + return false; + } + } + + info("Found a color. Node is part of color value."); + + return true; +} + +/** + * A generator that iterates recursively trough all child nodes of baseNode. + */ +function* iterateNodes(baseNode) { + yield baseNode; + + for (let child of baseNode.childNodes) { + yield* iterateNodes(child); + } +} + +/** + * Returns the root element for the given view, rule or computed. + */ +let rootElement = view => (view.element) ? view.element : view.styleDocument; diff --git a/browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-color_02.js b/browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-color_02.js new file mode 100644 index 00000000000..5120809d8c5 --- /dev/null +++ b/browser/devtools/styleinspector/test/browser_styleinspector_context-menu-copy-color_02.js @@ -0,0 +1,99 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test "Copy color" item of the context menu #2: Test that correct color is +// copied if the color changes. + +const TEST_COLOR = "#123ABC"; + +let test = asyncTest(function* () { + const PAGE_CONTENT = [ + '', + '
Testing the color picker tooltip!
' + ].join("\n"); + + yield addTab("data:text/html;charset=utf8,Test context menu Copy color"); + content.document.body.innerHTML = PAGE_CONTENT; + + let {inspector, view} = yield openRuleView(); + yield testCopyToClipboard(inspector, view); + yield testManualEdit(inspector, view); + yield testColorPickerEdit(inspector, view); +}); + +function* testCopyToClipboard(inspector, view) { + info("Testing that color is copied to clipboard"); + + yield selectNode("div", inspector); + + let win = view.doc.defaultView; + let element = getRuleViewProperty(view, "div", "color").valueSpan + .querySelector(".ruleview-colorswatch"); + + let popup = once(view._contextmenu, "popupshown"); + EventUtils.synthesizeMouseAtCenter(element, {button: 2, type: "contextmenu"}, win); + yield popup; + + ok(!view.menuitemCopyColor.hidden, "Copy color is visible"); + + yield waitForClipboard(() => view.menuitemCopyColor.click(), TEST_COLOR); + view._contextmenu.hidePopup(); +} + +function* testManualEdit(inspector, view) { + info("Testing manually edited colors"); + yield selectNode("div", inspector); + + let {valueSpan} = getRuleViewProperty(view, "div", "color"); + + let newColor = "#C9184E" + let editor = yield focusEditableField(valueSpan); + + info("Typing new value"); + let input = editor.input; + let onBlur = once(input, "blur"); + for (let ch of newColor + ";"){ + EventUtils.sendChar(ch, view.doc.defaultView); + } + + yield onBlur; + yield wait(1); + + let colorValue = getRuleViewProperty(view, "div", "color").valueSpan.firstChild; + is(colorValue.dataset.color, newColor, "data-color was updated"); + + view.doc.popupNode = colorValue; + view._isColorPopup(); + + is(view._colorToCopy, newColor, "_colorToCopy has the new value"); +} + +function* testColorPickerEdit(inspector, view) { + info("Testing colors edited via color picker"); + yield selectNode("div", inspector); + + let swatch = getRuleViewProperty(view, "div", "color").valueSpan + .querySelector(".ruleview-colorswatch"); + + info("Opening the color picker"); + let picker = view.colorPicker; + let onShown = picker.tooltip.once("shown"); + swatch.click(); + yield onShown; + + let rgbaColor = [83, 183, 89, 1]; + let rgbaColorText = "rgba(83, 183, 89, 1)"; + yield simulateColorPickerChange(picker, rgbaColor); + + is(swatch.parentNode.dataset.color, rgbaColorText, "data-color was updated"); + view.doc.popupNode = swatch; + view._isColorPopup(); + + is(view._colorToCopy, rgbaColorText, "_colorToCopy has the new value"); +} diff --git a/browser/devtools/styleinspector/test/browser_styleinspector_output-parser.js b/browser/devtools/styleinspector/test/browser_styleinspector_output-parser.js index 57ac8b29950..0bf9db457b3 100644 --- a/browser/devtools/styleinspector/test/browser_styleinspector_output-parser.js +++ b/browser/devtools/styleinspector/test/browser_styleinspector_output-parser.js @@ -73,7 +73,7 @@ function test() { name: "background-color", value: "transparent", test: fragment => { - is(countAll(fragment), 1); + is(countAll(fragment), 2); is(countColors(fragment), 1); is(fragment.textContent, "transparent"); } @@ -98,7 +98,7 @@ function test() { name: "border", value: "80em dotted pink", test: fragment => { - is(countAll(fragment), 1); + is(countAll(fragment), 2); is(countColors(fragment), 1); is(getColor(fragment), "pink"); } @@ -119,7 +119,7 @@ function test() { is(countUrls(fragment), 1); is(getColor(fragment), "red"); is(getUrl(fragment), "test.png"); - is(countAll(fragment), 2); + is(countAll(fragment), 3); } }, { @@ -130,7 +130,7 @@ function test() { is(countUrls(fragment), 1); is(getColor(fragment), "blue"); is(getUrl(fragment), "test.png"); - is(countAll(fragment), 2); + is(countAll(fragment), 3); } }, { @@ -163,7 +163,7 @@ function test() { name: "background", value: "linear-gradient(to right, rgba(183,222,237,1) 0%, rgba(33,180,226,1) 30%, rgba(31,170,217,.5) 44%, #F06 75%, red 100%)", test: fragment => { - is(countAll(fragment), 5); + is(countAll(fragment), 10); let allSwatches = fragment.querySelectorAll("." + COLOR_CLASS); is(allSwatches.length, 5); is(allSwatches[0].textContent, "rgba(183,222,237,1)"); @@ -177,7 +177,7 @@ function test() { name: "background", value: "-moz-radial-gradient(center 45deg, circle closest-side, orange 0%, red 100%)", test: fragment => { - is(countAll(fragment), 2); + is(countAll(fragment), 4); let allSwatches = fragment.querySelectorAll("." + COLOR_CLASS); is(allSwatches.length, 2); is(allSwatches[0].textContent, "orange"); @@ -188,7 +188,7 @@ function test() { name: "background", value: "white url(http://test.com/wow_such_image.png) no-repeat top left", test: fragment => { - is(countAll(fragment), 2); + is(countAll(fragment), 3); is(countUrls(fragment), 1); is(countColors(fragment), 1); } @@ -213,7 +213,7 @@ function test() { name: "background", value: "red url( \"http://wow.com/cool/../../../you're(doingit)wrong\" ) repeat center", test: fragment => { - is(countAll(fragment), 2); + is(countAll(fragment), 3); is(countColors(fragment), 1); is(getUrl(fragment), "http://wow.com/cool/../../../you're(doingit)wrong"); } diff --git a/toolkit/devtools/output-parser.js b/toolkit/devtools/output-parser.js index f02f3f5418b..737fb5fff27 100644 --- a/toolkit/devtools/output-parser.js +++ b/toolkit/devtools/output-parser.js @@ -328,18 +328,29 @@ OutputParser.prototype = { let colorObj = new colorUtils.CssColor(color); if (this._isValidColor(colorObj)) { + let container = this._createNode("span", { + "data-color": color + }); + if (options.colorSwatchClass) { - this._appendNode("span", { + let swatch = this._createNode("span", { class: options.colorSwatchClass, style: "background-color:" + color }); + container.appendChild(swatch); } + if (options.defaultColorType) { color = colorObj.toString(); + container.dataset["color"] = color; } - this._appendNode("span", { + + let value = this._createNode("span", { class: options.colorClass }, color); + + container.appendChild(value); + this.parsed.push(container); return true; } return false; @@ -380,7 +391,7 @@ OutputParser.prototype = { }, /** - * Append a node to the output. + * Create a node. * * @param {String} tagName * Tag type e.g. "div" @@ -389,8 +400,9 @@ OutputParser.prototype = { * @param {String} [value] * If a value is included it will be appended as a text node inside * the tag. This is useful e.g. for span tags. + * @return {Node} Newly created Node. */ - _appendNode: function(tagName, attributes, value="") { + _createNode: function(tagName, attributes, value="") { let win = Services.appShell.hiddenDOMWindow; let doc = win.document; let node = doc.createElementNS(HTML_NS, tagName); @@ -407,6 +419,22 @@ OutputParser.prototype = { node.appendChild(textNode); } + return node; + }, + + /** + * Append a node to the output. + * + * @param {String} tagName + * Tag type e.g. "div" + * @param {Object} attributes + * e.g. {class: "someClass", style: "cursor:pointer"}; + * @param {String} [value] + * If a value is included it will be appended as a text node inside + * the tag. This is useful e.g. for span tags. + */ + _appendNode: function(tagName, attributes, value="") { + let node = this._createNode(tagName, attributes, value); this.parsed.push(node); }, diff --git a/toolkit/locales/en-US/chrome/global/devtools/styleinspector.properties b/toolkit/locales/en-US/chrome/global/devtools/styleinspector.properties index 1fcc00e0f1a..91d232d6aec 100644 --- a/toolkit/locales/en-US/chrome/global/devtools/styleinspector.properties +++ b/toolkit/locales/en-US/chrome/global/devtools/styleinspector.properties @@ -80,6 +80,14 @@ ruleView.contextmenu.copy=Copy # the rule view context menu "Select all" entry. ruleView.contextmenu.copy.accessKey=C +# LOCALIZATION NOTE (ruleView.contextmenu.copyColor): Text displayed in the rule +# and computed view context menu when a color value was clicked. +ruleView.contextmenu.copyColor=Copy Color + +# LOCALIZATION NOTE (ruleView.contextmenu.copyColor.accessKey): Access key for +# the rule and computed view context menu "Copy Color" entry. +ruleView.contextmenu.copyColor.accessKey=L + # LOCALIZATION NOTE (ruleView.contextmenu.showOrigSources): Text displayed in the rule view # context menu. ruleView.contextmenu.showOrigSources=Show original sources From 3c509ac70d4bcf2aefd2c601077304c0e7c5e764 Mon Sep 17 00:00:00 2001 From: Jim Chen Date: Tue, 10 Jun 2014 12:33:00 -0400 Subject: [PATCH 09/23] Bug 1023469 - Replace generic observer with specific ones in browser.js. r=mfinkle --- mobile/android/chrome/content/browser.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index 417f165bfe5..078d4a6c2e0 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -121,10 +121,13 @@ XPCOMUtils.defineLazyModuleGetter(this, "CharsetMenu", Services.scriptloader.loadSubScript(script, sandbox); return sandbox[name]; }); - notifications.forEach(function (aNotification) { - Services.obs.addObserver(function(s, t, d) { - window[name].observe(s, t, d) - }, aNotification, false); + let observer = (s, t, d) => { + Services.obs.removeObserver(observer, t); + Services.obs.addObserver(window[name], t, false); + window[name].observe(s, t, d); // Explicitly notify new observer + }; + notifications.forEach((notification) => { + Services.obs.addObserver(observer, notification, false); }); }); @@ -135,10 +138,13 @@ XPCOMUtils.defineLazyModuleGetter(this, "CharsetMenu", ].forEach(module => { let [name, notifications, resource] = module; XPCOMUtils.defineLazyModuleGetter(this, name, resource); + let observer = (s, t, d) => { + Services.obs.removeObserver(observer, t); + Services.obs.addObserver(this[name], t, false); + this[name].observe(s, t, d); // Explicitly notify new observer + }; notifications.forEach(notification => { - Services.obs.addObserver((s,t,d) => { - this[name].observe(s,t,d) - }, notification, false); + Services.obs.addObserver(observer, notification, false); }); }); From 5a9d4114aac9fcad72eb69ce8380fd671a5a0286 Mon Sep 17 00:00:00 2001 From: William Lachance Date: Wed, 11 Jun 2014 10:27:20 -0400 Subject: [PATCH 10/23] Bug 1023883 - Update doc reference to manifestparser from manifestdestiny. r=ahal --- testing/mozbase/docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/mozbase/docs/index.rst b/testing/mozbase/docs/index.rst index 206e03c8630..86da2a14b7f 100644 --- a/testing/mozbase/docs/index.rst +++ b/testing/mozbase/docs/index.rst @@ -41,7 +41,7 @@ want to do then dive in! .. toctree:: :maxdepth: 2 - manifestdestiny + manifestparser gettinginfo setuprunning mozhttpd From 40a85318ecc1dab549c858bba76d9156d737d4a1 Mon Sep 17 00:00:00 2001 From: Dave Hunt Date: Wed, 11 Jun 2014 08:44:00 -0400 Subject: [PATCH 11/23] Bug 1023915 - [mozversion] Support targeting device by serial identifier. r=wlach --- .../mozversion/mozversion/mozversion.py | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/testing/mozbase/mozversion/mozversion/mozversion.py b/testing/mozbase/mozversion/mozversion/mozversion.py index 0f0430b7e2d..fb84550290c 100644 --- a/testing/mozbase/mozversion/mozversion/mozversion.py +++ b/testing/mozbase/mozversion/mozversion/mozversion.py @@ -33,6 +33,7 @@ class LocalAppNotFoundError(VersionError): INI_DATA_MAPPING = (('application', 'App'), ('platform', 'Build')) + class Version(mozlog.LoggingMixin): def __init__(self): @@ -62,6 +63,7 @@ class Version(mozlog.LoggingMixin): self._info['application_display_name'] = \ self._info.get('application_name') + class LocalFennecVersion(Version): def __init__(self, path, **kwargs): @@ -78,6 +80,7 @@ class LocalFennecVersion(Version): else: self.warn('Unable to find %s' % filename) + class LocalVersion(Version): def __init__(self, binary, **kwargs): @@ -168,11 +171,12 @@ class LocalB2GVersion(B2GVersion): class RemoteB2GVersion(B2GVersion): - def __init__(self, sources=None, dm_type='adb', host=None, **kwargs): + def __init__(self, sources=None, dm_type='adb', host=None, + device_serial=None, **kwargs): B2GVersion.__init__(self, sources, **kwargs) if dm_type == 'adb': - dm = mozdevice.DeviceManagerADB() + dm = mozdevice.DeviceManagerADB(deviceSerial=device_serial) elif dm_type == 'sut': if not host: raise Exception('A host for SUT must be supplied.') @@ -218,7 +222,8 @@ class RemoteB2GVersion(B2GVersion): self._info[desired_props[key]] = value -def get_version(binary=None, sources=None, dm_type=None, host=None): +def get_version(binary=None, sources=None, dm_type=None, host=None, + device_serial=None): """ Returns the application version information as a dict. You can specify a path to the binary of the application or an Android APK file (to get @@ -231,6 +236,7 @@ def get_version(binary=None, sources=None, dm_type=None, host=None): :param sources: Path to the sources.xml file (Firefox OS) :param dm_type: Device manager type. Must be 'adb' or 'sut' (Firefox OS) :param host: Host address of remote Firefox OS instance (SUT) + :param device_serial: Serial identifier of Firefox OS device (ADB) """ try: if binary and zipfile.is_zipfile(binary) and 'AndroidManifest.xml' in \ @@ -241,7 +247,8 @@ def get_version(binary=None, sources=None, dm_type=None, host=None): if version._info.get('application_name') == 'B2G': version = LocalB2GVersion(binary, sources=sources) except LocalAppNotFoundError: - version = RemoteB2GVersion(sources=sources, dm_type=dm_type, host=host) + version = RemoteB2GVersion(sources=sources, dm_type=dm_type, host=host, + device_serial=device_serial) return version._info @@ -253,13 +260,17 @@ def cli(args=sys.argv[1:]): parser.add_option('--sources', dest='sources', help='path to sources.xml (Firefox OS only)') + parser.add_option('--device', + help='serial identifier of device to target (Firefox OS ' + 'only)') (options, args) = parser.parse_args(args) dm_type = os.environ.get('DM_TRANS', 'adb') host = os.environ.get('TEST_DEVICE') version = get_version(binary=options.binary, sources=options.sources, - dm_type=dm_type, host=host) + dm_type=dm_type, host=host, + device_serial=options.device) for (key, value) in sorted(version.items()): if value: print '%s: %s' % (key, value) From f29a3bfb12714b2fd39a4c7bb30d7b59f0201b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Thu, 12 Jun 2014 17:56:22 +0200 Subject: [PATCH 12/23] Bug 1024496 - Call _updateScrollButtonsDisabledState after setting the notoverflowing attribute such that the scrolledtoend attribute isn't left behind. r=enndeakin --- toolkit/content/widgets/scrollbox.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/toolkit/content/widgets/scrollbox.xml b/toolkit/content/widgets/scrollbox.xml index 84db97fc6bf..66ae2d0eff3 100644 --- a/toolkit/content/widgets/scrollbox.xml +++ b/toolkit/content/widgets/scrollbox.xml @@ -558,6 +558,8 @@ try { // See bug 341047 and comments in overflow handler as to why // try..catch is needed here + this._updateScrollButtonsDisabledState(); + let childNodes = this._getScrollableElements(); if (childNodes && childNodes.length) this.ensureElementIsVisible(childNodes[0], false); From f33f4671314ede9f3e7398c1ba95a3414064077f Mon Sep 17 00:00:00 2001 From: Wes Johnston Date: Wed, 11 Jun 2014 11:00:17 -0700 Subject: [PATCH 13/23] Bug 1006158 - Add ability to pull in v7 libraries and google support libraries. r=nalexander --- build/autoconf/android.m4 | 50 +++++++++++++-- build/mobile/robocop/Makefile.in | 2 +- config/android-common.mk | 10 +-- mobile/android/base/AndroidManifest.xml.in | 5 ++ mobile/android/base/Makefile.in | 73 ++++++++++++++++++---- mobile/android/base/moz.build | 13 ++++ mobile/android/config/proguard.cfg | 2 + mobile/android/confvars.sh | 3 + 8 files changed, 133 insertions(+), 25 deletions(-) diff --git a/build/autoconf/android.m4 b/build/autoconf/android.m4 index 599f6e31531..6ea616d56ee 100644 --- a/build/autoconf/android.m4 +++ b/build/autoconf/android.m4 @@ -324,19 +324,61 @@ case "$target" in ANDROID_SDK="${android_sdk}" ANDROID_SDK_ROOT="${android_sdk_root}" - if test -e "${ANDROID_SDK_ROOT}/extras/android/compatibility/v4/android-support-v4.jar" ; then - ANDROID_COMPAT_LIB="${ANDROID_SDK_ROOT}/extras/android/compatibility/v4/android-support-v4.jar" + + AC_MSG_CHECKING([for compat library dirs]) + if test -e "${android_sdk_root}/extras/android/compatibility/v4/android-support-v4.jar" ; then + ANDROID_COMPAT_DIR_BASE="${android_sdk_root}/extras/android/compatibility"; else - ANDROID_COMPAT_LIB="${ANDROID_SDK_ROOT}/extras/android/support/v4/android-support-v4.jar"; + ANDROID_COMPAT_DIR_BASE="${android_sdk_root}/extras/android/support"; fi + AC_MSG_RESULT([$ANDROID_COMPAT_DIR_BASE]) + ANDROID_TOOLS="${android_tools}" ANDROID_PLATFORM_TOOLS="${android_platform_tools}" ANDROID_BUILD_TOOLS="${android_build_tools}" AC_SUBST(ANDROID_SDK_ROOT) AC_SUBST(ANDROID_SDK) + + ANDROID_COMPAT_LIB=$ANDROID_COMPAT_DIR_BASE/v4/android-support-v4.jar + AC_MSG_CHECKING([for v4 compat library]) AC_SUBST(ANDROID_COMPAT_LIB) if ! test -e $ANDROID_COMPAT_LIB ; then - AC_MSG_ERROR([You must download the Android support library when targeting Android. Run the Android SDK tool and install Android Support Library under Extras. See https://developer.android.com/tools/extras/support-library.html for more info. (looked for $ANDROID_COMPAT_LIB)]) + AC_MSG_ERROR([You must download the Android v4 support library when targeting Android. Run the Android SDK tool and install Android Support Library under Extras. See https://developer.android.com/tools/extras/support-library.html for more info. (looked for $ANDROID_COMPAT_LIB)]) + fi + AC_MSG_RESULT([$ANDROID_COMPAT_LIB]) + + if test -n "$MOZ_NATIVE_DEVICES" ; then + AC_SUBST(MOZ_NATIVE_DEVICES) + + AC_MSG_CHECKING([for google play services]) + GOOGLE_PLAY_SERVICES_LIB="${ANDROID_SDK_ROOT}/extras/google/google_play_services/libproject/google-play-services_lib/libs/google-play-services.jar" + GOOGLE_PLAY_SERVICES_RES="${ANDROID_SDK_ROOT}/extras/google/google_play_services/libproject/google-play-services_lib/res" + AC_SUBST(GOOGLE_PLAY_SERVICES_LIB) + AC_SUBST(GOOGLE_PLAY_SERVICES_RES) + if ! test -e $GOOGLE_PLAY_SERVICES_LIB ; then + AC_MSG_ERROR([You must download Google Play Services to build with native video casting support enabled. Run the Android SDK tool and install Google Play Services under Extras. See http://developer.android.com/google/play-services/setup.html for more info. (looked for $GOOGLE_PLAY_SERVICES_LIB) ]) + fi + AC_MSG_RESULT([$GOOGLE_PLAY_SERVICES_LIB]) + + ANDROID_APPCOMPAT_LIB="$ANDROID_COMPAT_DIR_BASE/v7/appcompat/libs/android-support-v7-appcompat.jar" + ANDROID_APPCOMPAT_RES="$ANDROID_COMPAT_DIR_BASE/v7/appcompat/res" + AC_MSG_CHECKING([for v7 appcompat library]) + if ! test -e $ANDROID_APPCOMPAT_LIB ; then + AC_MSG_ERROR([You must download the v7 app compat Android support library when targeting Android with native video casting support enabled. Run the Android SDK tool and install Android Support Library under Extras. See https://developer.android.com/tools/extras/support-library.html for more info. (looked for $ANDROID_APPCOMPAT_LIB)]) + fi + AC_MSG_RESULT([$ANDROID_APPCOMPAT_LIB]) + AC_SUBST(ANDROID_APPCOMPAT_LIB) + AC_SUBST(ANDROID_APPCOMPAT_RES) + + ANDROID_MEDIAROUTER_LIB="$ANDROID_COMPAT_DIR_BASE/v7/mediarouter/libs/android-support-v7-mediarouter.jar" + ANDROID_MEDIAROUTER_RES="$ANDROID_COMPAT_DIR_BASE/v7/mediarouter/res" + AC_MSG_CHECKING([for v7 mediarouter library]) + if ! test -e $ANDROID_MEDIAROUTER_LIB ; then + AC_MSG_ERROR([You must download the v7 media router Android support library when targeting Android with native video casting support enabled. Run the Android SDK tool and install Android Support Library under Extras. See https://developer.android.com/tools/extras/support-library.html for more info. (looked for $ANDROID_MEDIAROUTER_LIB)]) + fi + AC_MSG_RESULT([$ANDROID_MEDIAROUTER_LIB]) + AC_SUBST(ANDROID_MEDIAROUTER_LIB) + AC_SUBST(ANDROID_MEDIAROUTER_RES) fi MOZ_PATH_PROG(ZIPALIGN, zipalign, :, [$ANDROID_TOOLS]) diff --git a/build/mobile/robocop/Makefile.in b/build/mobile/robocop/Makefile.in index 4ea7500e4f7..cba99707832 100644 --- a/build/mobile/robocop/Makefile.in +++ b/build/mobile/robocop/Makefile.in @@ -95,7 +95,7 @@ GENERATED_DIRS += $(dir-tests) # being linked against them. This is a best effort to avoid getting # out of sync with base's build config. JARS_DIR := $(DEPTH)/mobile/android/base -JAVA_BOOTCLASSPATH := $(JAVA_BOOTCLASSPATH):$(subst $(NULL) ,:,$(wildcard $(JARS_DIR)/*.jar)) +JAVA_BOOTCLASSPATH := $(JAVA_BOOTCLASSPATH):$(subst $(NULL) ,:,$(wildcard $(JARS_DIR)/*.jar)):$(ANDROID_COMPAT_LIB) # We also want to re-compile classes.dex when the associated base # content changes. classes.dex: $(wildcard $(JARS_DIR)/*.jar) diff --git a/config/android-common.mk b/config/android-common.mk index ce123f9de6e..5b565dc85b7 100644 --- a/config/android-common.mk +++ b/config/android-common.mk @@ -2,16 +2,12 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -# Ensure JAVA_CLASSPATH and ANDROID_SDK are defined before including this file. +# Ensure ANDROID_SDK is defined before including this file. # We use common android defaults for boot class path and java version. ifndef ANDROID_SDK $(error ANDROID_SDK must be defined before including android-common.mk) endif -ifndef JAVA_CLASSPATH - $(error JAVA_CLASSPATH must be defined before including android-common.mk) -endif - # DEBUG_JARSIGNER always debug signs. DEBUG_JARSIGNER=$(PYTHON) $(abspath $(topsrcdir)/mobile/android/debug_sign_tool.py) \ --keytool=$(KEYTOOL) \ @@ -20,7 +16,7 @@ DEBUG_JARSIGNER=$(PYTHON) $(abspath $(topsrcdir)/mobile/android/debug_sign_tool. # For Android, this defaults to $(ANDROID_SDK)/android.jar ifndef JAVA_BOOTCLASSPATH - JAVA_BOOTCLASSPATH = $(ANDROID_SDK)/android.jar:$(ANDROID_COMPAT_LIB) + JAVA_BOOTCLASSPATH = $(ANDROID_SDK)/android.jar endif # For Android, we default to 1.5 @@ -31,7 +27,7 @@ endif JAVAC_FLAGS = \ -target $(JAVA_VERSION) \ -source $(JAVA_VERSION) \ - -classpath $(JAVA_CLASSPATH) \ + $(if $(JAVA_CLASSPATH),-classpath $(JAVA_CLASSPATH),) \ -bootclasspath $(JAVA_BOOTCLASSPATH) \ -encoding UTF8 \ -g:source,lines \ diff --git a/mobile/android/base/AndroidManifest.xml.in b/mobile/android/base/AndroidManifest.xml.in index 46d0e76c137..c667451c866 100644 --- a/mobile/android/base/AndroidManifest.xml.in +++ b/mobile/android/base/AndroidManifest.xml.in @@ -83,6 +83,11 @@ +#ifdef GOOGLE_PLAY_SERVICES + + +#endif + _*:!CVS:!thumbs.db:!picasa.ini:!*.scc:*~:\#*:*.rej:*.orig +extra_packages := $(subst $(NULL) ,:,$(strip $(extra_packages))) + # 1: target file. # 2: dependencies. # 3: name of ap_ file to write. @@ -301,10 +343,15 @@ ANDROID_AAPT_IGNORE := !.svn:!.git:.*:_*:!CVS:!thumbs.db:!picasa.ini:!*.scc define aapt_command $(1): $$(call mkdir_deps,$(filter-out ./,$(dir $(3) $(4) $(5)))) $(2) @$$(TOUCH) $$@ - $$(AAPT) package -f -M AndroidManifest.xml -I $$(ANDROID_SDK)/android.jar \ + $$(AAPT) package -f -m \ + -M AndroidManifest.xml \ + -I $(ANDROID_SDK)/android.jar \ --auto-add-overlay \ $$(addprefix -S ,$$(ANDROID_RES_DIRS)) \ - --custom-package org.mozilla.gecko --non-constant-id \ + $(if $(extra_res_dirs),$$(addprefix -S ,$$(extra_res_dirs)),) \ + $(if $(extra_packages),--extra-packages $$(extra_packages),) \ + --custom-package org.mozilla.gecko \ + --non-constant-id \ -F $(3) \ -J $(4) \ --output-text-symbols $(5) \ @@ -319,12 +366,12 @@ endef # toolkit/mozapps/installer/packager.mk. # .aapt.deps: $(all_resources) -$(eval $(call aapt_command,.aapt.deps,$(all_resources),gecko.ap_,$(gecko_package_dir)/,./)) +$(eval $(call aapt_command,.aapt.deps,$(all_resources),gecko.ap_,generated/,./)) # .aapt.nodeps: $(CURDIR)/AndroidManifest.xml FORCE $(eval $(call aapt_command,.aapt.nodeps,$(CURDIR)/AndroidManifest.xml FORCE,gecko-nodeps.ap_,gecko-nodeps/,gecko-nodeps/)) -fennec_ids.txt: $(gecko_package_dir)/R.java fennec-ids-generator.py +fennec_ids.txt: generated/org/mozilla/gecko/R.java fennec-ids-generator.py $(PYTHON) $(topsrcdir)/mobile/android/base/fennec-ids-generator.py -i $< -o $@ # Override the Java settings with some specific android settings diff --git a/mobile/android/base/moz.build b/mobile/android/base/moz.build index 674ad0b2e37..fee82bd095a 100644 --- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -16,6 +16,13 @@ resjar.sources = [] resjar.generated_sources += [ 'org/mozilla/gecko/R.java', ] + +if CONFIG['MOZ_NATIVE_DEVICES']: + resjar.generated_sources += ['com/google/android/gms/R.java'] + DEFINES["GOOGLE_PLAY_SERVICES"] = 1 + resjar.generated_sources += ['android/support/v7/appcompat/R.java'] + resjar.generated_sources += ['android/support/v7/mediarouter/R.java'] + resjar.javac_flags += ['-Xlint:all'] mgjar = add_java_jar('gecko-mozglue') @@ -470,6 +477,12 @@ gbjar.extra_jars = [ 'sync-thirdparty.jar', 'websockets.jar', ] + +if CONFIG['MOZ_NATIVE_DEVICES']: + gbjar.extra_jars += [CONFIG['ANDROID_APPCOMPAT_LIB']] + gbjar.extra_jars += [CONFIG['ANDROID_MEDIAROUTER_LIB']] + gbjar.extra_jars += [CONFIG['GOOGLE_PLAY_SERVICES_LIB']] + gbjar.javac_flags += ['-Xlint:all,-deprecation,-fallthrough'] spjar = add_java_jar('squareup-picasso') diff --git a/mobile/android/config/proguard.cfg b/mobile/android/config/proguard.cfg index feae3552e87..b6ff8e43606 100644 --- a/mobile/android/config/proguard.cfg +++ b/mobile/android/config/proguard.cfg @@ -194,6 +194,8 @@ *; } +-keep class **.R$* + # Disable obfuscation because it makes exception stack traces more difficult to read. -dontobfuscate diff --git a/mobile/android/confvars.sh b/mobile/android/confvars.sh index 2c813407638..168e7aec8e1 100644 --- a/mobile/android/confvars.sh +++ b/mobile/android/confvars.sh @@ -69,3 +69,6 @@ MOZ_LOCALE_SWITCHER=1 # Enable second screen and casting support for external devices. MOZ_DEVICES=1 + +# Enable second screen using native Android libraries +MOZ_NATIVE_DEVICES= From 88fe6fe0b3509fa2222302bd12c10cae90717538 Mon Sep 17 00:00:00 2001 From: Victor Porof Date: Thu, 12 Jun 2014 12:16:58 -0400 Subject: [PATCH 14/23] Bug 1022202 - Fix uncaught nsIScrollBoxObject.ensureElementIsVisible promise rejections in the netmonitor tests, r=dcamp --- browser/devtools/netmonitor/netmonitor-controller.js | 8 ++++++++ browser/devtools/netmonitor/netmonitor-view.js | 7 ++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/browser/devtools/netmonitor/netmonitor-controller.js b/browser/devtools/netmonitor/netmonitor-controller.js index e756c73a15d..78e3c7fd377 100644 --- a/browser/devtools/netmonitor/netmonitor-controller.js +++ b/browser/devtools/netmonitor/netmonitor-controller.js @@ -223,6 +223,14 @@ let NetMonitorController = { this.webConsoleClient = null; }, + /** + * Checks whether the netmonitor connection is active. + * @return boolean + */ + isConnected: function() { + return !!this.client; + }, + /** * Sets up a monitoring session. * diff --git a/browser/devtools/netmonitor/netmonitor-view.js b/browser/devtools/netmonitor/netmonitor-view.js index 792956ff864..6ec1aeeaf3c 100644 --- a/browser/devtools/netmonitor/netmonitor-view.js +++ b/browser/devtools/netmonitor/netmonitor-view.js @@ -1980,6 +1980,8 @@ NetworkDetailsView.prototype = { */ destroy: function() { dumpn("Destroying the NetworkDetailsView"); + + $("tabpanels", this.widget).removeEventListener("select", this._onTabSelect); }, /** @@ -2068,7 +2070,10 @@ NetworkDetailsView.prototype = { } populated[tab] = true; window.emit(EVENTS.TAB_UPDATED); - NetMonitorView.RequestsMenu.ensureSelectedItemIsVisible(); + + if (NetMonitorController.isConnected()) { + NetMonitorView.RequestsMenu.ensureSelectedItemIsVisible(); + } }); }, From 1c2571b7777b7925b19f9fecd805b89d6e97728c Mon Sep 17 00:00:00 2001 From: Victor Porof Date: Thu, 12 Jun 2014 12:16:59 -0400 Subject: [PATCH 15/23] Bug 985417 - Fix uncaught promise rejection when running browser_net_simple-request-data.js, r=dcamp --- .../test/browser_net_simple-init.js | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/browser/devtools/netmonitor/test/browser_net_simple-init.js b/browser/devtools/netmonitor/test/browser_net_simple-init.js index c273152bd78..e132f2ba6cc 100644 --- a/browser/devtools/netmonitor/test/browser_net_simple-init.js +++ b/browser/devtools/netmonitor/test/browser_net_simple-init.js @@ -6,6 +6,11 @@ */ function test() { + // These test suite functions are removed from the global scope inside a + // cleanup function. However, we still need them. + let gInfo = info; + let gOk = ok; + initNetMonitor(SIMPLE_URL).then(([aTab, aDebuggee, aMonitor]) => { info("Starting test... "); @@ -36,20 +41,20 @@ function test() { } function checkIfDestroyed(aTag) { - info("Checking if destruction is ok."); + gInfo("Checking if destruction is ok."); - ok(aMonitor._view, + gOk(aMonitor._view, "The network monitor view object still exists (" + aTag + ")."); - ok(aMonitor._controller, + gOk(aMonitor._controller, "The network monitor controller object still exists (" + aTag + ")."); - ok(aMonitor._controller._shutdown, + gOk(aMonitor._controller._shutdown, "The network monitor controller object still exists and is destroyed (" + aTag + ")."); - ok(!aMonitor._controller.client, + gOk(!aMonitor._controller.client, "There shouldn't be a client available after destruction (" + aTag + ")."); - ok(!aMonitor._controller.tabClient, + gOk(!aMonitor._controller.tabClient, "There shouldn't be a tabClient available after destruction (" + aTag + ")."); - ok(!aMonitor._controller.webConsoleClient, + gOk(!aMonitor._controller.webConsoleClient, "There shouldn't be a webConsoleClient available after destruction (" + aTag + ")."); } @@ -75,12 +80,12 @@ function test() { aMonitor._controller.shutdownNetMonitor() .then(() => { - info("Shutting down again shouldn't do anything special."); + gInfo("Shutting down again shouldn't do anything special."); checkIfDestroyed(2); return aMonitor._controller.disconnect(); }) .then(() => { - info("Disconnecting again shouldn't do anything special."); + gInfo("Disconnecting again shouldn't do anything special."); checkIfDestroyed(3); }); }); From 442a09ccdc40d71114bdfebc0ea12a9aec05b082 Mon Sep 17 00:00:00 2001 From: Victor Porof Date: Thu, 12 Jun 2014 12:16:59 -0400 Subject: [PATCH 16/23] Bug 1004104 - Disable caching when running netmonitor tests to hopefully fix some timeouts, r=dcamp --- .../test/browser_net_copy_as_curl.js | 5 +- .../test/browser_net_cyrillic-02.js | 2 +- .../test/browser_net_simple-request-data.js | 10 ++-- .../browser_net_simple-request-details.js | 52 +++++++++---------- browser/devtools/netmonitor/test/head.js | 45 ++++++++++++---- .../test/html_content-type-test-page.html | 3 ++ ..._content-type-without-cache-test-page.html | 3 ++ .../netmonitor/test/html_copy-as-curl.html | 3 ++ .../netmonitor/test/html_curl-utils.html | 3 ++ .../netmonitor/test/html_custom-get-page.html | 3 ++ .../test/html_cyrillic-test-page.html | 3 ++ .../test/html_filter-test-page.html | 3 ++ .../test/html_infinite-get-page.html | 3 ++ .../test/html_json-custom-mime-test-page.html | 3 ++ .../test/html_json-long-test-page.html | 3 ++ .../test/html_json-malformed-test-page.html | 3 ++ .../test/html_json-text-mime-test-page.html | 3 ++ .../netmonitor/test/html_jsonp-test-page.html | 3 ++ .../test/html_navigate-test-page.html | 3 ++ .../test/html_params-test-page.html | 3 ++ .../test/html_post-data-test-page.html | 3 ++ .../test/html_post-raw-test-page.html | 3 ++ .../html_post-raw-with-headers-test-page.html | 3 ++ .../test/html_simple-test-page.html | 3 ++ .../netmonitor/test/html_single-get-page.html | 6 ++- .../test/html_sorting-test-page.html | 3 ++ .../test/html_statistics-test-page.html | 5 +- .../test/html_status-codes-test-page.html | 3 ++ .../test/sjs_content-type-test-server.sjs | 42 ++++++++------- .../test/sjs_simple-test-server.sjs | 5 ++ .../test/sjs_sorting-test-server.sjs | 5 ++ .../test/sjs_status-codes-test-server.sjs | 5 ++ 32 files changed, 177 insertions(+), 68 deletions(-) diff --git a/browser/devtools/netmonitor/test/browser_net_copy_as_curl.js b/browser/devtools/netmonitor/test/browser_net_copy_as_curl.js index 102e37a33b8..6cff1456f6d 100644 --- a/browser/devtools/netmonitor/test/browser_net_copy_as_curl.js +++ b/browser/devtools/netmonitor/test/browser_net_copy_as_curl.js @@ -39,8 +39,9 @@ function test() { '-H "Connection: keep-alive"' ].join(" "); - const EXPECTED_RESULT = Services.appinfo.OS == "WINNT" ? - EXPECTED_WIN_RESULT : EXPECTED_POSIX_RESULT; + const EXPECTED_RESULT = Services.appinfo.OS == "WINNT" + ? EXPECTED_WIN_RESULT + : EXPECTED_POSIX_RESULT; let { NetMonitorView } = aMonitor.panelWin; let { RequestsMenu } = NetMonitorView; diff --git a/browser/devtools/netmonitor/test/browser_net_cyrillic-02.js b/browser/devtools/netmonitor/test/browser_net_cyrillic-02.js index 4fc8020d724..27b951d8653 100644 --- a/browser/devtools/netmonitor/test/browser_net_cyrillic-02.js +++ b/browser/devtools/netmonitor/test/browser_net_cyrillic-02.js @@ -31,7 +31,7 @@ function test() { waitFor(aMonitor.panelWin, RESPONSE_BODY_DISPLAYED).then(() => NetMonitorView.editor("#response-content-textarea") ).then((aEditor) => { - is(aEditor.getText().indexOf("\u044F"), 302, // я + is(aEditor.getText().indexOf("\u044F"), 486, // я "The text shown in the source editor is incorrect."); is(aEditor.getMode(), Editor.modes.html, "The mode active in the source editor is incorrect."); diff --git a/browser/devtools/netmonitor/test/browser_net_simple-request-data.js b/browser/devtools/netmonitor/test/browser_net_simple-request-data.js index 08424933796..0a0375996f0 100644 --- a/browser/devtools/netmonitor/test/browser_net_simple-request-data.js +++ b/browser/devtools/netmonitor/test/browser_net_simple-request-data.js @@ -86,10 +86,8 @@ function test() { ok(requestItem.attachment.requestHeaders, "There should be a requestHeaders attachment available."); - ok(requestItem.attachment.requestHeaders.headers.length >= 6, + is(requestItem.attachment.requestHeaders.headers.length, 8, "The requestHeaders attachment has an incorrect |headers| property."); - // Can't test for an exact total number of headers, because it seems to - // vary across pgo/non-pgo builds. isnot(requestItem.attachment.requestHeaders.headersSize, 0, "The requestHeaders attachment has an incorrect |headersSize| property."); // Can't test for the exact request headers size because the value may @@ -118,9 +116,9 @@ function test() { ok(requestItem.attachment.responseHeaders, "There should be a responseHeaders attachment available."); - is(requestItem.attachment.responseHeaders.headers.length, 6, + is(requestItem.attachment.responseHeaders.headers.length, 9, "The responseHeaders attachment has an incorrect |headers| property."); - is(requestItem.attachment.responseHeaders.headersSize, 173, + is(requestItem.attachment.responseHeaders.headersSize, 255, "The responseHeaders attachment has an incorrect |headersSize| property."); verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS); @@ -146,7 +144,7 @@ function test() { "The status attachment has an incorrect value."); is(requestItem.attachment.statusText, "Och Aye", "The statusText attachment has an incorrect value."); - is(requestItem.attachment.headersSize, 173, + is(requestItem.attachment.headersSize, 255, "The headersSize attachment has an incorrect value."); verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS, { diff --git a/browser/devtools/netmonitor/test/browser_net_simple-request-details.js b/browser/devtools/netmonitor/test/browser_net_simple-request-details.js index af9850608c3..bae5c0e4553 100644 --- a/browser/devtools/netmonitor/test/browser_net_simple-request-details.js +++ b/browser/devtools/netmonitor/test/browser_net_simple-request-details.js @@ -63,10 +63,8 @@ function test() { is(tabpanel.querySelectorAll(".variables-view-scope").length, 2, "There should be 2 header scopes displayed in this tabpanel."); - ok(tabpanel.querySelectorAll(".variable-or-property").length >= 12, - "There should be at least 12 header values displayed in this tabpanel."); - // Can't test for an exact total number of headers, because it seems to - // vary across pgo/non-pgo builds. + is(tabpanel.querySelectorAll(".variable-or-property").length, 17, + "There should be 17 header values displayed in this tabpanel."); is(tabpanel.querySelectorAll(".variables-view-empty-notice").length, 0, "The empty notice should not be displayed in this tabpanel."); @@ -76,7 +74,7 @@ function test() { is(responseScope.querySelector(".name").getAttribute("value"), L10N.getStr("responseHeaders") + " (" + - L10N.getFormatStr("networkMenu.sizeKB", L10N.numberWithDecimals(173/1024, 3)) + ")", + L10N.getFormatStr("networkMenu.sizeKB", L10N.numberWithDecimals(255/1024, 3)) + ")", "The response headers scope doesn't have the correct title."); ok(requestScope.querySelector(".name").getAttribute("value").contains( @@ -87,20 +85,24 @@ function test() { // sure it's smaller than 1 MB though, so it starts with a 0. is(responseScope.querySelectorAll(".variables-view-variable .name")[0].getAttribute("value"), - "Connection", "The first response header name was incorrect."); + "Cache-Control", "The first response header name was incorrect."); is(responseScope.querySelectorAll(".variables-view-variable .value")[0].getAttribute("value"), - "\"close\"", "The first response header value was incorrect."); + "\"no-cache, no-store, must-revalidate\"", "The first response header value was incorrect."); is(responseScope.querySelectorAll(".variables-view-variable .name")[1].getAttribute("value"), - "Content-Length", "The second response header name was incorrect."); + "Connection", "The second response header name was incorrect."); is(responseScope.querySelectorAll(".variables-view-variable .value")[1].getAttribute("value"), - "\"12\"", "The second response header value was incorrect."); + "\"close\"", "The second response header value was incorrect."); is(responseScope.querySelectorAll(".variables-view-variable .name")[2].getAttribute("value"), - "Content-Type", "The third response header name was incorrect."); + "Content-Length", "The third response header name was incorrect."); is(responseScope.querySelectorAll(".variables-view-variable .value")[2].getAttribute("value"), - "\"text/plain; charset=utf-8\"", "The third response header value was incorrect."); - is(responseScope.querySelectorAll(".variables-view-variable .name")[5].getAttribute("value"), + "\"12\"", "The third response header value was incorrect."); + is(responseScope.querySelectorAll(".variables-view-variable .name")[3].getAttribute("value"), + "Content-Type", "The fourth response header name was incorrect."); + is(responseScope.querySelectorAll(".variables-view-variable .value")[3].getAttribute("value"), + "\"text/plain; charset=utf-8\"", "The fourth response header value was incorrect."); + is(responseScope.querySelectorAll(".variables-view-variable .name")[8].getAttribute("value"), "foo-bar", "The last response header name was incorrect."); - is(responseScope.querySelectorAll(".variables-view-variable .value")[5].getAttribute("value"), + is(responseScope.querySelectorAll(".variables-view-variable .value")[8].getAttribute("value"), "\"baz\"", "The last response header value was incorrect."); is(requestScope.querySelectorAll(".variables-view-variable .name")[0].getAttribute("value"), @@ -108,21 +110,17 @@ function test() { is(requestScope.querySelectorAll(".variables-view-variable .value")[0].getAttribute("value"), "\"example.com\"", "The first request header value was incorrect."); is(requestScope.querySelectorAll(".variables-view-variable .name")[5].getAttribute("value"), - "Connection", "The penultimate request header name was incorrect."); + "Connection", "The ante-penultimate request header name was incorrect."); is(requestScope.querySelectorAll(".variables-view-variable .value")[5].getAttribute("value"), - "\"keep-alive\"", "The penultimate request header value was incorrect."); - - let lastReqHeaderName = requestScope.querySelectorAll(".variables-view-variable .name")[6]; - let lastReqHeaderValue = requestScope.querySelectorAll(".variables-view-variable .value")[6]; - if (lastReqHeaderName && lastReqHeaderValue) { - is(lastReqHeaderName.getAttribute("value"), - "Cache-Control", "The last request header name was incorrect."); - is(lastReqHeaderValue.getAttribute("value"), - "\"max-age=0\"", "The last request header value was incorrect."); - } else { - info("The number of request headers was 6 instead of 7. Technically, " + - "not a failure in this particular test, but needs investigation."); - } + "\"keep-alive\"", "The ante-penultimate request header value was incorrect."); + is(requestScope.querySelectorAll(".variables-view-variable .name")[6].getAttribute("value"), + "Pragma", "The penultimate request header name was incorrect."); + is(requestScope.querySelectorAll(".variables-view-variable .value")[6].getAttribute("value"), + "\"no-cache\"", "The penultimate request header value was incorrect."); + is(requestScope.querySelectorAll(".variables-view-variable .name")[7].getAttribute("value"), + "Cache-Control", "The last request header name was incorrect."); + is(requestScope.querySelectorAll(".variables-view-variable .value")[7].getAttribute("value"), + "\"no-cache\"", "The last request header value was incorrect."); } function testCookiesTab() { diff --git a/browser/devtools/netmonitor/test/head.js b/browser/devtools/netmonitor/test/head.js index bbc9fb72438..492fb005961 100644 --- a/browser/devtools/netmonitor/test/head.js +++ b/browser/devtools/netmonitor/test/head.js @@ -97,24 +97,49 @@ function removeTab(aTab, aWindow) { targetBrowser.removeTab(aTab); } +function waitForNavigation(aTarget) { + let deferred = promise.defer(); + aTarget.once("will-navigate", () => { + aTarget.once("navigate", () => { + deferred.resolve(); + }); + }); + return deferred.promise; +} + +function reconfigureTab(aTarget, aOptions) { + let deferred = promise.defer(); + aTarget.activeTab.reconfigure(aOptions, deferred.resolve); + return deferred.promise; +}; + +function toggleCache(aTarget, aEnabled) { + let options = { cacheEnabled: aEnabled, performReload: true }; + let navigationFinished = waitForNavigation(aTarget); + return reconfigureTab(aTarget, options).then(() => navigationFinished); +} + function initNetMonitor(aUrl, aWindow) { info("Initializing a network monitor pane."); - return addTab(aUrl).then((aTab) => { + return Task.spawn(function*() { + let tab = yield addTab(aUrl); info("Net tab added successfully: " + aUrl); - let deferred = promise.defer(); - let debuggee = aTab.linkedBrowser.contentWindow.wrappedJSObject; - let target = TargetFactory.forTab(aTab); + let debuggee = tab.linkedBrowser.contentWindow.wrappedJSObject; + let target = TargetFactory.forTab(tab); - gDevTools.showToolbox(target, "netmonitor").then((aToolbox) => { - info("Netork monitor pane shown successfully."); + yield target.makeRemote(); + info("Target remoted."); - let monitor = aToolbox.getCurrentPanel(); - deferred.resolve([aTab, debuggee, monitor]); - }); + yield toggleCache(target, false); + info("Network cache disabled"); - return deferred.promise; + let toolbox = yield gDevTools.showToolbox(target, "netmonitor"); + info("Netork monitor pane shown successfully."); + + let monitor = toolbox.getCurrentPanel(); + return [tab, debuggee, monitor]; }); } diff --git a/browser/devtools/netmonitor/test/html_content-type-test-page.html b/browser/devtools/netmonitor/test/html_content-type-test-page.html index 27016275664..23ecf1f442d 100644 --- a/browser/devtools/netmonitor/test/html_content-type-test-page.html +++ b/browser/devtools/netmonitor/test/html_content-type-test-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_content-type-without-cache-test-page.html b/browser/devtools/netmonitor/test/html_content-type-without-cache-test-page.html index 7c6163ae717..40dad0c7076 100644 --- a/browser/devtools/netmonitor/test/html_content-type-without-cache-test-page.html +++ b/browser/devtools/netmonitor/test/html_content-type-without-cache-test-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_copy-as-curl.html b/browser/devtools/netmonitor/test/html_copy-as-curl.html index 482d8cd630e..3ddcfbcedb6 100644 --- a/browser/devtools/netmonitor/test/html_copy-as-curl.html +++ b/browser/devtools/netmonitor/test/html_copy-as-curl.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_curl-utils.html b/browser/devtools/netmonitor/test/html_curl-utils.html index 466edcb9bb9..8ff7ecdf0da 100644 --- a/browser/devtools/netmonitor/test/html_curl-utils.html +++ b/browser/devtools/netmonitor/test/html_curl-utils.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_custom-get-page.html b/browser/devtools/netmonitor/test/html_custom-get-page.html index 1e8c2a0ecf3..19e40f93a3b 100644 --- a/browser/devtools/netmonitor/test/html_custom-get-page.html +++ b/browser/devtools/netmonitor/test/html_custom-get-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_cyrillic-test-page.html b/browser/devtools/netmonitor/test/html_cyrillic-test-page.html index ff3e1b67ed4..8735ac674f6 100644 --- a/browser/devtools/netmonitor/test/html_cyrillic-test-page.html +++ b/browser/devtools/netmonitor/test/html_cyrillic-test-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_filter-test-page.html b/browser/devtools/netmonitor/test/html_filter-test-page.html index 05b5032af4a..eb5d02ed9b9 100644 --- a/browser/devtools/netmonitor/test/html_filter-test-page.html +++ b/browser/devtools/netmonitor/test/html_filter-test-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_infinite-get-page.html b/browser/devtools/netmonitor/test/html_infinite-get-page.html index 1c5ca167205..f51b718adc9 100644 --- a/browser/devtools/netmonitor/test/html_infinite-get-page.html +++ b/browser/devtools/netmonitor/test/html_infinite-get-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_json-custom-mime-test-page.html b/browser/devtools/netmonitor/test/html_json-custom-mime-test-page.html index 17dd8c1e7c2..646fc60ea89 100644 --- a/browser/devtools/netmonitor/test/html_json-custom-mime-test-page.html +++ b/browser/devtools/netmonitor/test/html_json-custom-mime-test-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_json-long-test-page.html b/browser/devtools/netmonitor/test/html_json-long-test-page.html index bb64de1bc4a..b538b4c2787 100644 --- a/browser/devtools/netmonitor/test/html_json-long-test-page.html +++ b/browser/devtools/netmonitor/test/html_json-long-test-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_json-malformed-test-page.html b/browser/devtools/netmonitor/test/html_json-malformed-test-page.html index 423ef811976..0c8627ab5aa 100644 --- a/browser/devtools/netmonitor/test/html_json-malformed-test-page.html +++ b/browser/devtools/netmonitor/test/html_json-malformed-test-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_json-text-mime-test-page.html b/browser/devtools/netmonitor/test/html_json-text-mime-test-page.html index 76f7af3c398..2c64e253156 100644 --- a/browser/devtools/netmonitor/test/html_json-text-mime-test-page.html +++ b/browser/devtools/netmonitor/test/html_json-text-mime-test-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_jsonp-test-page.html b/browser/devtools/netmonitor/test/html_jsonp-test-page.html index 4be5209c21f..78c0da08be1 100644 --- a/browser/devtools/netmonitor/test/html_jsonp-test-page.html +++ b/browser/devtools/netmonitor/test/html_jsonp-test-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_navigate-test-page.html b/browser/devtools/netmonitor/test/html_navigate-test-page.html index ab28e8545a3..23f00f3dfdd 100644 --- a/browser/devtools/netmonitor/test/html_navigate-test-page.html +++ b/browser/devtools/netmonitor/test/html_navigate-test-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_params-test-page.html b/browser/devtools/netmonitor/test/html_params-test-page.html index 8c581a0d7ef..de1394b8c7c 100644 --- a/browser/devtools/netmonitor/test/html_params-test-page.html +++ b/browser/devtools/netmonitor/test/html_params-test-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page diff --git a/browser/devtools/netmonitor/test/html_post-data-test-page.html b/browser/devtools/netmonitor/test/html_post-data-test-page.html index cb7de21926c..8dedc7b606c 100644 --- a/browser/devtools/netmonitor/test/html_post-data-test-page.html +++ b/browser/devtools/netmonitor/test/html_post-data-test-page.html @@ -5,6 +5,9 @@ + + + Network Monitor test page