зеркало из https://github.com/mozilla/gecko-dev.git
Merge fx-team to central, a=merge
This commit is contained in:
Коммит
e076823935
|
@ -676,7 +676,7 @@
|
|||
|
||||
<hbox id="nav-bar-customization-target" flex="1">
|
||||
<toolbaritem id="urlbar-container" flex="400" persist="width"
|
||||
title="&locationItem.title;" removable="false"
|
||||
removable="false"
|
||||
class="chromeclass-location" overflows="false">
|
||||
<toolbarbutton id="back-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
label="&backCmd.label;"
|
||||
|
@ -799,16 +799,13 @@
|
|||
<toolbarbutton id="urlbar-go-button"
|
||||
class="chromeclass-toolbar-additional"
|
||||
onclick="gURLBar.handleCommand(event);"
|
||||
aria-label="&goEndCap.tooltip;"
|
||||
tooltiptext="&goEndCap.tooltip;"/>
|
||||
<toolbarbutton id="urlbar-reload-button"
|
||||
class="chromeclass-toolbar-additional"
|
||||
command="Browser:ReloadOrDuplicate"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
aria-label="&reloadButton.tooltip;"
|
||||
tooltiptext="&reloadButton.tooltip;"/>
|
||||
<toolbarbutton id="urlbar-stop-button"
|
||||
aria-label="&stopButton.tooltip;"
|
||||
class="chromeclass-toolbar-additional"
|
||||
command="Browser:Stop"
|
||||
tooltiptext="&stopButton.tooltip;"/>
|
||||
|
|
|
@ -3,5 +3,7 @@ support-files =
|
|||
file_dom_notifications.html
|
||||
|
||||
[browser_notification_open_settings.js]
|
||||
[browser_notification_remove_permission.js]
|
||||
skip-if = e10s
|
||||
[browser_notification_tab_switching.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 1100662 - content access causing uncaught exception - Error: cannot ipc non-cpow object at chrome://mochitests/content/browser/browser/base/content/test/general/browser_notification_tab_switching.js:32 (or in RemoteAddonsChild.jsm)
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
"use strict";
|
||||
|
||||
var tab;
|
||||
var notification;
|
||||
var notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
|
||||
var alertWindowClosed = false;
|
||||
var permRemoved = false;
|
||||
|
||||
function test () {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let pm = Services.perms;
|
||||
registerCleanupFunction(function() {
|
||||
pm.remove(makeURI(notificationURL), "desktop-notification");
|
||||
gBrowser.removeTab(tab);
|
||||
window.restore();
|
||||
});
|
||||
|
||||
pm.add(makeURI(notificationURL), "desktop-notification", pm.ALLOW_ACTION);
|
||||
|
||||
tab = gBrowser.addTab(notificationURL);
|
||||
gBrowser.selectedTab = tab;
|
||||
tab.linkedBrowser.addEventListener("load", onLoad, true);
|
||||
}
|
||||
|
||||
function onLoad() {
|
||||
tab.linkedBrowser.removeEventListener("load", onLoad, true);
|
||||
let win = tab.linkedBrowser.contentWindow.wrappedJSObject;
|
||||
notification = win.showNotification2();
|
||||
notification.addEventListener("show", onAlertShowing);
|
||||
}
|
||||
|
||||
function onAlertShowing() {
|
||||
info("Notification alert showing");
|
||||
notification.removeEventListener("show", onAlertShowing);
|
||||
|
||||
let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
|
||||
if (!alertWindow) {
|
||||
ok(true, "Notifications don't use XUL windows on all platforms.");
|
||||
notification.close();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
ok(Services.perms.testExactPermission(makeURI(notificationURL), "desktop-notification"),
|
||||
"Permission should exist prior to removal");
|
||||
let disableForOriginMenuItem = alertWindow.document.getElementById("disableForOriginMenuItem");
|
||||
is(disableForOriginMenuItem.localName, "menuitem", "menuitem found");
|
||||
Services.obs.addObserver(permObserver, "perm-changed", false);
|
||||
alertWindow.addEventListener("beforeunload", onAlertClosing);
|
||||
disableForOriginMenuItem.click();
|
||||
info("Clicked on disable-for-origin menuitem")
|
||||
}
|
||||
|
||||
function permObserver(subject, topic, data) {
|
||||
if (topic != "perm-changed") {
|
||||
return;
|
||||
}
|
||||
|
||||
let permission = subject.QueryInterface(Ci.nsIPermission);
|
||||
is(permission.type, "desktop-notification", "desktop-notification permission changed");
|
||||
is(data, "deleted", "desktop-notification permission deleted");
|
||||
|
||||
Services.obs.removeObserver(permObserver, "perm-changed");
|
||||
permRemoved = true;
|
||||
if (alertWindowClosed) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
function onAlertClosing(event) {
|
||||
event.target.removeEventListener("beforeunload", onAlertClosing);
|
||||
|
||||
alertWindowClosed = true;
|
||||
if (permRemoved) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ function onAlertShowing() {
|
|||
|
||||
let alertWindow = Services.wm.getMostRecentWindow("alert:alert");
|
||||
if (!alertWindow) {
|
||||
todo(false, "Notifications don't use XUL windows on all platforms.");
|
||||
ok(true, "Notifications don't use XUL windows on all platforms.");
|
||||
notification.close();
|
||||
newWindowOpenedFromTab.close();
|
||||
finish();
|
||||
|
|
|
@ -218,8 +218,6 @@ These should match what Safari and other Apple applications use on OS X Lion. --
|
|||
|
||||
<!ENTITY urlbar.toggleAutocomplete.label "Toggle the autocomplete popup">
|
||||
|
||||
|
||||
<!ENTITY locationItem.title "Location">
|
||||
<!ENTITY searchItem.title "Search">
|
||||
|
||||
<!-- Toolbar items -->
|
||||
|
|
|
@ -125,3 +125,8 @@
|
|||
shown in the inspector contextual-menu for the item that lets users take
|
||||
a screenshot of the currently selected node. -->
|
||||
<!ENTITY inspectorScreenshotNode.label "Screenshot Node">
|
||||
|
||||
<!-- LOCALIZATION NOTE (inspectorDuplicateNode.label): This is the label
|
||||
shown in the inspector contextual-menu for the item that lets users
|
||||
duplicate the currently selected node. -->
|
||||
<!ENTITY inspectorDuplicateNode.label "Duplicate Node">
|
||||
|
|
|
@ -893,7 +893,7 @@ toolbar .toolbarbutton-1:-moz-any(@primaryToolbarButtons@) > :-moz-any(.toolbarb
|
|||
transition: opacity 0.15s ease;
|
||||
}
|
||||
|
||||
#navigator-toolbox:not(:hover) .urlbar-history-dropmarker {
|
||||
#navigator-toolbox:not(:hover) #urlbar:not([focused]) > .urlbar-textbox-container > .urlbar-history-dropmarker {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
%filter substitution
|
||||
|
||||
%define toolbarHighlight rgba(255,255,255,.3)
|
||||
%define toolbarHighlight rgba(255,255,255,.4)
|
||||
%define fgTabTexture linear-gradient(transparent 2px, @toolbarHighlight@ 2px, @toolbarHighlight@)
|
||||
%define fgTabTextureLWT @fgTabTexture@
|
||||
%define fgTabBackgroundColor -moz-dialog
|
||||
|
|
|
@ -1697,7 +1697,7 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
|||
transition: opacity 0.15s ease;
|
||||
}
|
||||
|
||||
#navigator-toolbox:not(:hover) .urlbar-history-dropmarker {
|
||||
#navigator-toolbox:not(:hover) #urlbar:not([focused]) > .urlbar-textbox-container > .urlbar-history-dropmarker {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1410,7 +1410,7 @@ html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
|
|||
transition: opacity 0.15s ease;
|
||||
}
|
||||
|
||||
#navigator-toolbox:not(:hover) .urlbar-history-dropmarker {
|
||||
#navigator-toolbox:not(:hover) #urlbar:not([focused]) > .urlbar-textbox-container > .urlbar-history-dropmarker {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
%filter substitution
|
||||
|
||||
%define toolbarHighlight rgba(255,255,255,.3)
|
||||
%define toolbarHighlight rgba(255,255,255,.4)
|
||||
%define fgTabTexture linear-gradient(transparent 2px, @toolbarHighlight@ 2px, @toolbarHighlight@)
|
||||
%define fgTabBackgroundColor -moz-dialog
|
||||
%define fgTabTextureLWT @fgTabTexture@
|
||||
|
|
|
@ -654,6 +654,9 @@ InspectorPanel.prototype = {
|
|||
!this.selection.isPseudoElementNode();
|
||||
let isEditableElement = isSelectionElement &&
|
||||
!this.selection.isAnonymousNode();
|
||||
let isDuplicatableElement = isSelectionElement &&
|
||||
!this.selection.isAnonymousNode() &&
|
||||
!this.selection.isRoot();
|
||||
let isScreenshotable = isSelectionElement &&
|
||||
this.canGetUniqueSelector &&
|
||||
this.selection.nodeFront.isTreeDisplayed;
|
||||
|
@ -683,6 +686,7 @@ InspectorPanel.prototype = {
|
|||
// "Copy outer HTML", "Scroll Into View" & "Screenshot Node" as appropriate
|
||||
let unique = this.panelDoc.getElementById("node-menu-copyuniqueselector");
|
||||
let screenshot = this.panelDoc.getElementById("node-menu-screenshotnode");
|
||||
let duplicateNode = this.panelDoc.getElementById("node-menu-duplicatenode");
|
||||
let copyInnerHTML = this.panelDoc.getElementById("node-menu-copyinner");
|
||||
let copyOuterHTML = this.panelDoc.getElementById("node-menu-copyouter");
|
||||
let scrollIntoView = this.panelDoc.getElementById("node-menu-scrollnodeintoview");
|
||||
|
@ -700,10 +704,20 @@ InspectorPanel.prototype = {
|
|||
expandAll.removeAttribute("disabled");
|
||||
}
|
||||
|
||||
this._target.actorHasMethod("domwalker", "duplicateNode").then(value => {
|
||||
duplicateNode.hidden = !value;
|
||||
});
|
||||
this._target.actorHasMethod("domnode", "scrollIntoView").then(value => {
|
||||
scrollIntoView.hidden = !value;
|
||||
});
|
||||
|
||||
if (isDuplicatableElement) {
|
||||
duplicateNode.removeAttribute("disabled");
|
||||
}
|
||||
else {
|
||||
duplicateNode.setAttribute("disabled", "true");
|
||||
}
|
||||
|
||||
if (isSelectionElement) {
|
||||
unique.removeAttribute("disabled");
|
||||
copyInnerHTML.removeAttribute("disabled");
|
||||
|
@ -1177,6 +1191,20 @@ InspectorPanel.prototype = {
|
|||
this.selection.nodeFront.scrollIntoView();
|
||||
},
|
||||
|
||||
/**
|
||||
* Duplicate the selected node
|
||||
*/
|
||||
duplicateNode: function() {
|
||||
let selection = this.selection;
|
||||
if (!selection.isElementNode() ||
|
||||
selection.isRoot() ||
|
||||
selection.isAnonymousNode() ||
|
||||
selection.isPseudoElementNode()) {
|
||||
return;
|
||||
}
|
||||
this.walker.duplicateNode(selection.nodeFront).catch(e => console.error(e));
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete the selected node.
|
||||
*/
|
||||
|
|
|
@ -103,6 +103,9 @@
|
|||
<menuitem id="node-menu-screenshotnode"
|
||||
label="&inspectorScreenshotNode.label;"
|
||||
oncommand="inspector.screenshotNode()" />
|
||||
<menuitem id="node-menu-duplicatenode"
|
||||
label="&inspectorDuplicateNode.label;"
|
||||
oncommand="inspector.duplicateNode()"/>
|
||||
<menuitem id="node-menu-delete"
|
||||
label="&inspectorHTMLDelete.label;"
|
||||
accesskey="&inspectorHTMLDelete.accesskey;"
|
||||
|
|
|
@ -4,17 +4,14 @@ http://creativecommons.org/publicdomain/zero/1.0/ */
|
|||
"use strict";
|
||||
|
||||
// Tests for menuitem functionality that doesn't fit into any specific category
|
||||
|
||||
const TEST_URL = TEST_URL_ROOT + "doc_inspector_menu.html";
|
||||
|
||||
add_task(function* () {
|
||||
let { inspector, toolbox, testActor } = yield openInspectorForURL(TEST_URL);
|
||||
|
||||
yield testShowDOMProperties();
|
||||
yield testDuplicateNode();
|
||||
yield testDeleteNode();
|
||||
yield testDeleteRootNode();
|
||||
yield testScrollIntoView();
|
||||
|
||||
function* testShowDOMProperties() {
|
||||
info("Testing 'Show DOM Properties' menu item.");
|
||||
let showDOMPropertiesNode = inspector.panelDoc.getElementById("node-menu-showdomproperties");
|
||||
|
@ -29,20 +26,38 @@ add_task(function* () {
|
|||
let webconsoleUI = toolbox.getPanel("webconsole").hud.ui;
|
||||
let messagesAdded = webconsoleUI.once("new-messages");
|
||||
yield messagesAdded;
|
||||
|
||||
info("Checking if 'inspect($0)' was evaluated");
|
||||
ok(webconsoleUI.jsterm.history[0] === 'inspect($0)');
|
||||
|
||||
yield toolbox.toggleSplitConsole();
|
||||
}
|
||||
function* testDuplicateNode() {
|
||||
info("Testing 'Duplicate Node' menu item for normal elements.");
|
||||
|
||||
yield selectNode(".duplicate", inspector);
|
||||
is((yield testActor.getNumberOfElementMatches(".duplicate")), 1,
|
||||
"There should initially be 1 .duplicate node");
|
||||
|
||||
let menuItem = inspector.panelDoc.getElementById("node-menu-duplicatenode");
|
||||
ok(menuItem, "'Duplicate node' menu item should exist");
|
||||
|
||||
info("Triggering 'Duplicate Node' and waiting for inspector to update");
|
||||
let updated = inspector.once("markupmutation");
|
||||
dispatchCommandEvent(menuItem);
|
||||
yield updated;
|
||||
|
||||
is((yield testActor.getNumberOfElementMatches(".duplicate")), 2,
|
||||
"The duplicated node should be in the markup.");
|
||||
|
||||
let container = yield getContainerForSelector(".duplicate + .duplicate",
|
||||
inspector);
|
||||
ok(container, "A MarkupContainer should be created for the new node");
|
||||
}
|
||||
|
||||
function* testDeleteNode() {
|
||||
info("Testing 'Delete Node' menu item for normal elements.");
|
||||
|
||||
yield selectNode("#delete", inspector);
|
||||
let deleteNode = inspector.panelDoc.getElementById("node-menu-delete");
|
||||
ok(deleteNode, "the popup menu has a delete menu item");
|
||||
|
||||
let updated = inspector.once("inspector-updated");
|
||||
|
||||
info("Triggering 'Delete Node' and waiting for inspector to update");
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
</div>
|
||||
<p data-id="copy">Paragraph for testing copy</p>
|
||||
<p id="sensitivity">Paragraph for sensitivity</p>
|
||||
<p class="duplicate">This will be duplicated</p>
|
||||
<p id="delete">This has to be deleted</p>
|
||||
<img id="copyimage" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==" />
|
||||
<div id="hiddenElement" style="display: none;">
|
||||
|
|
|
@ -224,14 +224,14 @@ devtools.jar:
|
|||
skin/themes/images/breadcrumbs-scrollbutton@2x.png (themes/images/breadcrumbs-scrollbutton@2x.png)
|
||||
skin/themes/animationinspector.css (themes/animationinspector.css)
|
||||
skin/themes/eyedropper.css (themes/eyedropper.css)
|
||||
* skin/themes/canvasdebugger.css (themes/canvasdebugger.css)
|
||||
skin/themes/canvasdebugger.css (themes/canvasdebugger.css)
|
||||
skin/themes/debugger.css (themes/debugger.css)
|
||||
* skin/themes/netmonitor.css (themes/netmonitor.css)
|
||||
skin/themes/performance.css (themes/performance.css)
|
||||
skin/themes/memory.css (themes/memory.css)
|
||||
skin/themes/promisedebugger.css (themes/promisedebugger.css)
|
||||
skin/themes/images/timeline-filter.svg (themes/images/timeline-filter.svg)
|
||||
* skin/themes/scratchpad.css (themes/scratchpad.css)
|
||||
skin/themes/scratchpad.css (themes/scratchpad.css)
|
||||
skin/themes/shadereditor.css (themes/shadereditor.css)
|
||||
skin/themes/storage.css (themes/storage.css)
|
||||
* skin/themes/splitview.css (themes/splitview.css)
|
||||
|
|
|
@ -82,6 +82,21 @@ var TestActor = exports.TestActor = protocol.ActorClass({
|
|||
}
|
||||
return node;
|
||||
},
|
||||
/**
|
||||
* Helper to get the number of elements matching a selector
|
||||
* @param {string} CSS selector.
|
||||
*/
|
||||
getNumberOfElementMatches: protocol.method(function (selector,
|
||||
root=this.content.document) {
|
||||
return root.querySelectorAll(selector).length;
|
||||
}, {
|
||||
request: {
|
||||
selector: Arg(0, "string"),
|
||||
},
|
||||
response: {
|
||||
value: RetVal("number")
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Get a value for a given attribute name, on one of the elements of the box
|
||||
|
|
|
@ -2,14 +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/. */
|
||||
|
||||
%filter substitution
|
||||
%define darkCheckerboardBackground #000
|
||||
%define lightCheckerboardBackground #fff
|
||||
%define checkerboardCell rgba(128,128,128,0.2)
|
||||
%define checkerboardPattern linear-gradient(45deg, @checkerboardCell@ 25%, transparent 25%, transparent 75%, @checkerboardCell@ 75%, @checkerboardCell@), linear-gradient(45deg, @checkerboardCell@ 25%, transparent 25%, transparent 75%, @checkerboardCell@ 75%, @checkerboardCell@)
|
||||
%define gutterWidth 3em
|
||||
%define gutterPaddingStart 22px
|
||||
|
||||
:root {
|
||||
--gutter-width: 3em;
|
||||
--gutter-padding-start: 22px;
|
||||
--checkerboard-pattern: linear-gradient(45deg, rgba(128,128,128,0.2) 25%, transparent 25%, transparent 75%, rgba(128,128,128,0.2) 75%, rgba(128,128,128,0.2)),
|
||||
linear-gradient(45deg, rgba(128,128,128,0.2) 25%, transparent 25%, transparent 75%, rgba(128,128,128,0.2) 75%, rgba(128,128,128,0.2));
|
||||
}
|
||||
/* Reload and waiting notices */
|
||||
|
||||
.notice-container {
|
||||
|
@ -35,22 +33,9 @@
|
|||
|
||||
/* Snapshots pane */
|
||||
|
||||
#snapshots-pane > tabs {
|
||||
-moz-border-end: 1px solid;
|
||||
}
|
||||
|
||||
#snapshots-pane > tabs,
|
||||
#snapshots-pane .devtools-toolbar {
|
||||
-moz-border-end: 1px solid;
|
||||
}
|
||||
|
||||
.theme-dark #snapshots-pane > tabs,
|
||||
.theme-dark #snapshots-pane .devtools-toolbar {
|
||||
-moz-border-end-color: black; /* Match the splitter color. */
|
||||
}
|
||||
|
||||
.theme-light #snapshots-pane > tabs,
|
||||
.theme-light #snapshots-pane .devtools-toolbar {
|
||||
-moz-border-end-color: #aaa; /* Match the splitter color. */
|
||||
-moz-border-end: 1px solid var(--theme-splitter-color);
|
||||
}
|
||||
|
||||
#record-snapshot {
|
||||
|
@ -65,7 +50,7 @@
|
|||
|
||||
.snapshot-item-thumbnail {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
background-image: @checkerboardPattern@;
|
||||
background-image: var(--checkerboard-pattern);
|
||||
background-size: 12px 12px, 12px 12px;
|
||||
background-position: 0px 0px, 6px 6px;
|
||||
background-repeat: repeat, repeat;
|
||||
|
@ -75,12 +60,8 @@
|
|||
transform: scaleY(-1);
|
||||
}
|
||||
|
||||
.theme-dark .snapshot-item-thumbnail {
|
||||
background-color: @darkCheckerboardBackground@;
|
||||
}
|
||||
|
||||
.theme-light .snapshot-item-thumbnail {
|
||||
background-color: @lightCheckerboardBackground@;
|
||||
.snapshot-item-thumbnail {
|
||||
background-color: var(--theme-body-background);
|
||||
}
|
||||
|
||||
.snapshot-item-details {
|
||||
|
@ -234,9 +215,9 @@
|
|||
}
|
||||
|
||||
.call-item-gutter {
|
||||
width: calc(@gutterWidth@ + @gutterPaddingStart@);
|
||||
-moz-padding-start: @gutterPaddingStart@;
|
||||
-moz-padding-end: 4px;
|
||||
width: calc(var(--gutter-width) + var(--gutter-padding-start));
|
||||
padding-inline-start: var(--gutter-padding-start);
|
||||
padding-inline-end: 4px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
-moz-border-end: 1px solid;
|
||||
|
@ -300,7 +281,7 @@
|
|||
}
|
||||
|
||||
.call-item-stack {
|
||||
-moz-padding-start: calc(@gutterWidth@ + @gutterPaddingStart@);
|
||||
-moz-padding-start: calc(var(--gutter-width) + var(--gutter-padding-start));
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
|
@ -345,20 +326,13 @@
|
|||
/* Rendering preview */
|
||||
|
||||
#screenshot-container {
|
||||
background-image: @checkerboardPattern@;
|
||||
background-color: var(--theme-body-background);
|
||||
background-image: var(--checkerboard-pattern);
|
||||
background-size: 30px 30px, 30px 30px;
|
||||
background-position: 0px 0px, 15px 15px;
|
||||
background-repeat: repeat, repeat;
|
||||
}
|
||||
|
||||
.theme-dark #screenshot-container {
|
||||
background-color: @darkCheckerboardBackground@;
|
||||
}
|
||||
|
||||
.theme-light #screenshot-container {
|
||||
background-color: @lightCheckerboardBackground@;
|
||||
}
|
||||
|
||||
@media (min-width: 701px) {
|
||||
#screenshot-container {
|
||||
width: 30vw;
|
||||
|
@ -403,22 +377,22 @@
|
|||
/* Snapshot filmstrip */
|
||||
|
||||
#snapshot-filmstrip {
|
||||
border-top: 1px solid var(--theme-splitter-color);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.theme-dark #snapshot-filmstrip {
|
||||
border-top: 1px solid #000;
|
||||
color: var(--theme-selection-color);
|
||||
}
|
||||
|
||||
.theme-light #snapshot-filmstrip {
|
||||
border-top: 1px solid #aaa;
|
||||
color: var(--theme-body-color-alt);
|
||||
}
|
||||
|
||||
.filmstrip-thumbnail {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
background-image: @checkerboardPattern@;
|
||||
background-color: var(--theme-body-background);
|
||||
background-image: var(--checkerboard-pattern);
|
||||
background-size: 12px 12px, 12px 12px;
|
||||
background-position: 0px -1px, 6px 5px;
|
||||
background-repeat: repeat, repeat;
|
||||
|
@ -426,6 +400,7 @@
|
|||
cursor: pointer;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
border-inline-end: 1px solid var(--theme-splitter-color);
|
||||
transition: opacity 0.1s ease-in-out;
|
||||
}
|
||||
|
||||
|
@ -433,18 +408,6 @@
|
|||
transform: scaleY(-1);
|
||||
}
|
||||
|
||||
.theme-dark .filmstrip-thumbnail {
|
||||
background-color: @darkCheckerboardBackground@;
|
||||
}
|
||||
|
||||
.theme-light .filmstrip-thumbnail {
|
||||
background-color: @lightCheckerboardBackground@;
|
||||
}
|
||||
|
||||
.filmstrip-thumbnail {
|
||||
-moz-border-end: 1px solid var(--theme-splitter-color)
|
||||
}
|
||||
|
||||
#snapshot-filmstrip > .filmstrip-thumbnail:hover,
|
||||
#snapshot-filmstrip:not(:hover) > .filmstrip-thumbnail[highlighted] {
|
||||
border: 1px solid var(--theme-highlight-blue);
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
%if 0
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
%endif
|
||||
|
||||
#scratchpad-sidebar > tabs {
|
||||
height: 0;
|
||||
|
|
|
@ -67,14 +67,7 @@
|
|||
.stylesheet-sidebar {
|
||||
max-width: 400px;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.theme-light .stylesheet-sidebar {
|
||||
border-color: #aaa; /* Splitters */
|
||||
}
|
||||
|
||||
.theme-dark .stylesheet-sidebar {
|
||||
border-color: #000; /* Splitters */
|
||||
border-color: var(--theme-splitter-color);
|
||||
}
|
||||
|
||||
.theme-light .media-rule-label {
|
||||
|
|
|
@ -563,47 +563,21 @@
|
|||
}
|
||||
|
||||
.devtools-sidebar-tabs tabs > tab:first-child {
|
||||
-moz-border-start-width: 0;
|
||||
border-inline-start-width: 0;
|
||||
}
|
||||
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab:hover {
|
||||
background: hsla(206,37%,4%,.2);
|
||||
.devtools-sidebar-tabs tabs > tab:hover {
|
||||
background: rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab:hover:active {
|
||||
background: hsla(206,37%,4%,.4);
|
||||
.devtools-sidebar-tabs tabs > tab:hover:active {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab[selected] + tab:hover {
|
||||
background: hsla(206,37%,4%,.2);
|
||||
}
|
||||
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab[selected] + tab:hover:active {
|
||||
background: hsla(206,37%,4%,.4);
|
||||
}
|
||||
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab[selected],
|
||||
.theme-dark .devtools-sidebar-tabs tabs > tab[selected]:hover:active {
|
||||
.devtools-sidebar-tabs tabs > tab[selected],
|
||||
.devtools-sidebar-tabs tabs > tab[selected]:hover:active {
|
||||
color: var(--theme-selection-color);
|
||||
background: #1d4f73;
|
||||
}
|
||||
|
||||
.theme-light .devtools-sidebar-tabs tabs > tab:hover {
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
.theme-light .devtools-sidebar-tabs tabs > tab:hover:active {
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
.theme-light .devtools-sidebar-tabs tabs > tab[selected] + tab:hover {
|
||||
background: #ddd;
|
||||
}
|
||||
|
||||
.theme-light .devtools-sidebar-tabs tabs > tab[selected],
|
||||
.theme-light .devtools-sidebar-tabs tabs > tab[selected]:hover:active {
|
||||
color: var(--theme-selection-color);
|
||||
background: #4c9ed9;
|
||||
background: var(--theme-selection-background);
|
||||
}
|
||||
|
||||
/* Toolbox - moved from toolbox.css.
|
||||
|
|
|
@ -30,10 +30,10 @@ svg {
|
|||
}
|
||||
|
||||
.theme-dark .edgePath path {
|
||||
stroke: #b6babf; /* Grey foreground text */
|
||||
stroke: var(--theme-body-color-alt);
|
||||
}
|
||||
.theme-light .edgePath path {
|
||||
stroke: #aaaaaa; /* Splitters */
|
||||
stroke: var(--theme-splitter-color);
|
||||
}
|
||||
|
||||
/* AudioParam connection edges */
|
||||
|
@ -42,27 +42,21 @@ g.edgePath.param-connection {
|
|||
}
|
||||
|
||||
.theme-dark .edgePath.param-connection path {
|
||||
stroke: #b6babf; /* Grey foreground text */
|
||||
stroke: var(--theme-body-color-alt);
|
||||
}
|
||||
.theme-light .edgePath.param-connection path {
|
||||
stroke: #aaaaaa; /* Splitters */
|
||||
stroke: var(--theme-splitter-color);
|
||||
}
|
||||
|
||||
/* Labels in AudioParam connection should have background that match
|
||||
* the main background so there's whitespace around the label, on top of the
|
||||
* dotted lines. */
|
||||
.theme-dark g.edgeLabel rect {
|
||||
fill: #14171a;
|
||||
g.edgeLabel rect {
|
||||
fill: var(--theme-body-background);
|
||||
}
|
||||
.theme-light g.edgeLabel rect {
|
||||
fill: #fcfcfc; /* Background - Editor */
|
||||
}
|
||||
.theme-dark g.edgeLabel tspan {
|
||||
g.edgeLabel tspan {
|
||||
fill: var(--theme-body-color-alt);
|
||||
}
|
||||
.theme-light g.edgeLabel tspan {
|
||||
fill: #585959; /* Grey foreground text */
|
||||
}
|
||||
|
||||
/* Audio Nodes */
|
||||
.nodes rect {
|
||||
|
@ -219,11 +213,8 @@ text {
|
|||
background-color: transparent;
|
||||
}
|
||||
|
||||
.theme-dark #audio-node-toolbar toolbarbutton[checked] {
|
||||
background-color: #1d4f73; /* Select Highlight Blue */
|
||||
}
|
||||
.theme-light #audio-node-toolbar toolbarbutton[checked] {
|
||||
background-color: #4c9ed9; /* Select Highlight Blue */
|
||||
#audio-node-toolbar toolbarbutton[checked] {
|
||||
background-color: var(--theme-selection-background);
|
||||
}
|
||||
|
||||
/* don't invert checked buttons so we can have white icons on light theme */
|
||||
|
|
|
@ -26,7 +26,7 @@ a {
|
|||
.message > .prefix,
|
||||
.message > .timestamp {
|
||||
flex: none;
|
||||
color: GrayText;
|
||||
color: var(--theme-comment);
|
||||
margin: 3px 6px 0 0;
|
||||
}
|
||||
|
||||
|
@ -131,11 +131,6 @@ a {
|
|||
margin-top: 0;
|
||||
}
|
||||
|
||||
.jsterm-input-container {
|
||||
border-top-width: 1px;
|
||||
border-top-style: solid;
|
||||
}
|
||||
|
||||
#output-wrapper {
|
||||
direction: ltr;
|
||||
overflow: auto;
|
||||
|
@ -253,11 +248,11 @@ a {
|
|||
}
|
||||
|
||||
.message[category=network].mixed-content .url {
|
||||
color: #FF0000;
|
||||
color: var(--theme-highlight-red);
|
||||
}
|
||||
|
||||
.message .learn-more-link {
|
||||
color: -moz-nativehyperlinktext;
|
||||
color: var(--theme-highlight-blue);
|
||||
margin: 0 6px;
|
||||
}
|
||||
|
||||
|
@ -360,6 +355,18 @@ a {
|
|||
}
|
||||
|
||||
/* JSTerm Styles */
|
||||
.jsterm-input-container {
|
||||
background-color: var(--theme-tab-toolbar-background);
|
||||
border-top: 1px solid var(--theme-splitter-color);
|
||||
}
|
||||
|
||||
.theme-light .jsterm-input-container {
|
||||
/* For light theme use a white background for the input - it looks better
|
||||
than off-white */
|
||||
background-color: #fff;
|
||||
border-top-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.jsterm-input-node,
|
||||
.jsterm-complete-node {
|
||||
border: none;
|
||||
|
@ -368,10 +375,15 @@ a {
|
|||
background-color: transparent;
|
||||
}
|
||||
|
||||
.jsterm-complete-node {
|
||||
color: var(--theme-comment);
|
||||
}
|
||||
|
||||
.jsterm-input-node {
|
||||
background-image: -moz-image-rect(url("chrome://devtools/skin/themes/images/commandline-icon.png"), 0, 32, 16, 16);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 16px 16px;
|
||||
color: var(--theme-content-color1);
|
||||
}
|
||||
|
||||
@media (min-resolution: 1.1dppx) {
|
||||
|
@ -398,7 +410,7 @@ a {
|
|||
margin-top: 5px;
|
||||
margin-bottom: 15px;
|
||||
-moz-margin-end: 15px;
|
||||
border: 1px solid rgba(128, 128, 128, .5);
|
||||
border: 1px solid var(--theme-splitter-color);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
|
@ -442,6 +454,11 @@ a {
|
|||
.navigation-marker .url {
|
||||
-moz-padding-end: 9px;
|
||||
text-decoration: none;
|
||||
background: var(--theme-body-background);
|
||||
}
|
||||
|
||||
.theme-light .navigation-marker .url {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.stacktrace {
|
||||
|
@ -451,7 +468,7 @@ a {
|
|||
margin: 5px 0 0 0;
|
||||
max-height: 10em;
|
||||
overflow-y: auto;
|
||||
border: 1px solid rgb(200,200,200);
|
||||
border: 1px solid var(--theme-splitter-color);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
|
@ -514,49 +531,6 @@ a {
|
|||
background-position: -16px 0;
|
||||
}
|
||||
|
||||
.jsterm-input-container {
|
||||
background-color: var(--theme-tab-toolbar-background);
|
||||
border-color: var(--theme-body-background);
|
||||
}
|
||||
|
||||
.jsterm-input-node {
|
||||
color: var(--theme-content-color1);
|
||||
}
|
||||
|
||||
.jsterm-complete-node {
|
||||
color: var(--theme-comment);
|
||||
}
|
||||
|
||||
.navigation-marker .url {
|
||||
background: var(--theme-body-background);
|
||||
}
|
||||
|
||||
.theme-dark .inlined-variables-view iframe {
|
||||
border-color: #333;
|
||||
}
|
||||
|
||||
.theme-dark .stacktrace {
|
||||
border-color: #333;
|
||||
}
|
||||
|
||||
.theme-light .jsterm-input-container {
|
||||
/* For light theme use a white background for the input - it looks better
|
||||
than off-white */
|
||||
background-color: #fff;
|
||||
border-color: ThreeDShadow;
|
||||
}
|
||||
.theme-light .navigation-marker .url {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.theme-light .inlined-variables-view iframe {
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
.theme-light .stacktrace {
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.message > .timestamp {
|
||||
display: none;
|
||||
|
|
|
@ -2592,6 +2592,21 @@ var WalkerActor = protocol.ActorClass({
|
|||
response: RetVal("disconnectedNodeArray")
|
||||
}),
|
||||
|
||||
/**
|
||||
* Duplicate a specified node
|
||||
*
|
||||
* @param {NodeActor} node The node to duplicate.
|
||||
*/
|
||||
duplicateNode: method(function({rawNode}) {
|
||||
let clonedNode = rawNode.cloneNode(true);
|
||||
rawNode.parentNode.insertBefore(clonedNode, rawNode.nextSibling);
|
||||
}, {
|
||||
request: {
|
||||
node: Arg(0, "domnode")
|
||||
},
|
||||
response: {}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Test whether a node is a document or a document element.
|
||||
*
|
||||
|
|
|
@ -57,6 +57,7 @@ skip-if = buildapp == 'mulet'
|
|||
[test_inspector-changeattrs.html]
|
||||
[test_inspector-changevalue.html]
|
||||
[test_inspector-dead-nodes.html]
|
||||
[test_inspector-duplicate-node.html]
|
||||
[test_inspector_getImageData.html]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[test_inspector_getImageDataFromURL.html]
|
||||
|
|
|
@ -80,12 +80,11 @@
|
|||
<select multiple><option>one</option><option>two</option></select>
|
||||
<div id="pseudo"><span>middle</span></div>
|
||||
<div id="pseudo-empty"></div>
|
||||
|
||||
<div id="shadow">light dom</div>
|
||||
|
||||
<object>
|
||||
<div id="1"></div>
|
||||
</object>
|
||||
<div class="node-to-duplicate"></div>
|
||||
<div id="scroll-into-view" style="margin-top: 1000px;">scroll</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1208864
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1208864</title>
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
<script type="application/javascript;version=1.8" src="inspector-helpers.js"></script>
|
||||
<script type="application/javascript;version=1.8">
|
||||
const inspector = require("devtools/server/actors/inspector");
|
||||
|
||||
window.onload = function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
var gInspectee = null;
|
||||
var gClient = null;
|
||||
var gWalker = null;
|
||||
|
||||
function assertOwnership() {
|
||||
assertOwnershipTrees(gWalker);
|
||||
}
|
||||
|
||||
addTest(function setup() {
|
||||
let url = document.getElementById("inspectorContent").href;
|
||||
attachURL(url, function(err, client, tab, doc) {
|
||||
gInspectee = doc;
|
||||
let {InspectorFront} = require("devtools/server/actors/inspector");
|
||||
let inspector = InspectorFront(client, tab);
|
||||
promiseDone(inspector.getWalker().then(walker => {
|
||||
ok(walker, "getWalker() should return an actor.");
|
||||
gClient = client;
|
||||
gWalker = walker;
|
||||
}).then(runNextTest));
|
||||
});
|
||||
});
|
||||
|
||||
addTest(Task.async(function* testDuplicateNode() {
|
||||
let className = ".node-to-duplicate";
|
||||
let matches = yield gWalker.querySelectorAll(gWalker.rootNode, className);
|
||||
is(matches.length, 1, "There should initially be one node to duplicate.");
|
||||
|
||||
let nodeFront = yield gWalker.querySelector(gWalker.rootNode, className);
|
||||
yield gWalker.duplicateNode(nodeFront);
|
||||
|
||||
matches = yield gWalker.querySelectorAll(gWalker.rootNode, className);
|
||||
is(matches.length, 2, "The node should now be duplicated.");
|
||||
|
||||
runNextTest();
|
||||
}));
|
||||
|
||||
addTest(function cleanup() {
|
||||
delete gWalker;
|
||||
delete gInspectee;
|
||||
delete gClient;
|
||||
runNextTest();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1208864">Mozilla Bug 1208864</a>
|
||||
<a id="inspectorContent" target="_blank" href="inspector-traversal-data.html">Test Document</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -458,6 +458,25 @@ exports.dbg_assert = function dbg_assert(cond, e) {
|
|||
}
|
||||
};
|
||||
|
||||
exports.defineLazyGetter(this, "AppConstants", () => {
|
||||
const scope = {};
|
||||
Cu.import("resource://gre/modules/AppConstants.jsm", scope);
|
||||
return scope.AppConstants;
|
||||
});
|
||||
|
||||
/**
|
||||
* No operation. The empty function.
|
||||
*/
|
||||
exports.noop = function () { };
|
||||
|
||||
function reallyAssert(condition, message) {
|
||||
if (!condition) {
|
||||
const err = new Error("Assertion failure: " + message);
|
||||
exports.reportException("DevToolsUtils.assert", err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DevToolsUtils.assert(condition, message)
|
||||
*
|
||||
|
@ -477,23 +496,11 @@ exports.dbg_assert = function dbg_assert(cond, e) {
|
|||
* This is an improvement over `dbg_assert`, which doesn't actually cause any
|
||||
* fatal behavior, and is therefore much easier to accidentally ignore.
|
||||
*/
|
||||
exports.defineLazyGetter(exports, "assert", () => {
|
||||
function noop(condition, msg) { }
|
||||
|
||||
function assert(condition, message) {
|
||||
if (!condition) {
|
||||
const err = new Error("Assertion failure: " + message);
|
||||
exports.reportException("DevToolsUtils.assert", err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const scope = {};
|
||||
Cu.import("resource://gre/modules/AppConstants.jsm", scope);
|
||||
const { DEBUG, DEBUG_JS_MODULES } = scope.AppConstants;
|
||||
|
||||
return (DEBUG || DEBUG_JS_MODULES || exports.testing) ? assert : noop;
|
||||
});
|
||||
Object.defineProperty(exports, "assert", {
|
||||
get: () => (AppConstants.DEBUG || AppConstants.DEBUG_JS_MODULES || this.testing)
|
||||
? reallyAssert
|
||||
: exports.noop,
|
||||
})
|
||||
|
||||
/**
|
||||
* Defines a getter on a specified object for a module. The module will not
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/devtools/DeserializedNode.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/Nullable.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RefCounted.h"
|
||||
|
@ -139,6 +140,15 @@ public:
|
|||
|
||||
void TakeCensus(JSContext* cx, JS::HandleObject options,
|
||||
JS::MutableHandleValue rval, ErrorResult& rv);
|
||||
|
||||
dom::Nullable<uint64_t> GetCreationTime() {
|
||||
static const uint64_t maxTime = uint64_t(1) << 53;
|
||||
if (timestamp.isSome() && timestamp.ref() <= maxTime) {
|
||||
return dom::Nullable<uint64_t>(timestamp.ref());
|
||||
}
|
||||
|
||||
return dom::Nullable<uint64_t>();
|
||||
}
|
||||
};
|
||||
|
||||
// A `CoreDumpWriter` is given the data we wish to save in a core dump and
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// HeapSnapshot.prototype.creationTime returns the expected time.
|
||||
|
||||
function waitForTenMilliseconds() {
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < 10) ;
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
const start = Date.now() * 1000;
|
||||
do_print("start = " + start);
|
||||
|
||||
// Because Date.now() is less precise than the snapshot's time stamp, give it
|
||||
// a little bit of head room.
|
||||
waitForTenMilliseconds();
|
||||
const path = ChromeUtils.saveHeapSnapshot({ runtime: true });
|
||||
waitForTenMilliseconds();
|
||||
|
||||
const end = Date.now() * 1000;
|
||||
do_print("end = " + end);
|
||||
|
||||
const snapshot = ChromeUtils.readHeapSnapshot(path);
|
||||
do_print("snapshot.creationTime = " + snapshot.creationTime);
|
||||
|
||||
ok(snapshot.creationTime >= start);
|
||||
ok(snapshot.creationTime <= end);
|
||||
}
|
|
@ -25,6 +25,7 @@ support-files =
|
|||
[test_HeapAnalyses_takeCensus_03.js]
|
||||
[test_HeapAnalyses_takeCensus_04.js]
|
||||
[test_HeapAnalyses_takeCensus_05.js]
|
||||
[test_HeapSnapshot_creationTime_01.js]
|
||||
[test_HeapSnapshot_takeCensus_01.js]
|
||||
[test_HeapSnapshot_takeCensus_02.js]
|
||||
[test_HeapSnapshot_takeCensus_03.js]
|
||||
|
|
|
@ -9,6 +9,11 @@ const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
|||
|
||||
// Register a console listener, so console messages don't just disappear
|
||||
// into the ether.
|
||||
|
||||
// If for whatever reason the test needs to post console errors that aren't
|
||||
// failures, set this to true.
|
||||
var ALLOW_CONSOLE_ERRORS = false;
|
||||
|
||||
var errorCount = 0;
|
||||
var listener = {
|
||||
observe: function (aMessage) {
|
||||
|
@ -35,7 +40,10 @@ var listener = {
|
|||
while (DebuggerServer.xpcInspector.eventLoopNestLevel > 0) {
|
||||
DebuggerServer.xpcInspector.exitNestedEventLoop();
|
||||
}
|
||||
do_throw("head_dbg.js got console message: " + string + "\n");
|
||||
|
||||
if (!ALLOW_CONSOLE_ERRORS) {
|
||||
do_throw("head_devtools.js got console message: " + string + "\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test DevToolsUtils.assert
|
||||
|
||||
ALLOW_CONSOLE_ERRORS = true;
|
||||
|
||||
function run_test() {
|
||||
// Enable assertions.
|
||||
DevToolsUtils.testing = true;
|
||||
|
||||
const { assert } = DevToolsUtils;
|
||||
equal(typeof assert, "function");
|
||||
|
||||
try {
|
||||
assert(true, "this assertion should not fail");
|
||||
} catch (e) {
|
||||
// If you catch assertion failures in practice, I will hunt you down. I get
|
||||
// email notifications every time it happens.
|
||||
ok(false, "Should not get an error for an assertion that should not fail. Got "
|
||||
+ DevToolsUtils.safeErrorString(e));
|
||||
}
|
||||
|
||||
let assertionFailed = false;
|
||||
try {
|
||||
assert(false, "this assertion should fail");
|
||||
} catch (e) {
|
||||
ok(e.message.startsWith("Assertion failure:"),
|
||||
"Should be an assertion failure error");
|
||||
assertionFailed = true;
|
||||
}
|
||||
|
||||
ok(assertionFailed,
|
||||
"The assertion should have failed, which should throw an error when assertions are enabled.");
|
||||
}
|
|
@ -6,6 +6,7 @@ skip-if = toolkit == 'android' || toolkit == 'gonk'
|
|||
support-files =
|
||||
exposeLoader.js
|
||||
|
||||
[test_assert.js]
|
||||
[test_fetch-chrome.js]
|
||||
[test_fetch-file.js]
|
||||
[test_fetch-http.js]
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
*/
|
||||
[ChromeOnly, Exposed=(Window,System,Worker)]
|
||||
interface HeapSnapshot {
|
||||
/**
|
||||
* A time stamp of when the heap snapshot was taken, if available. Units are
|
||||
* microseconds since midnight (00:00:00) 1 January 1970 UTC.
|
||||
*/
|
||||
readonly attribute unsigned long long? creationTime;
|
||||
|
||||
/**
|
||||
* Take a census of the heap snapshot.
|
||||
*
|
||||
|
|
|
@ -463,7 +463,9 @@ $(abspath $(DIST)/fennec/$(OMNIJAR_NAME)): FORCE
|
|||
$(RM) $(DIST)/fennec/$(notdir $(OMNIJAR_NAME))
|
||||
|
||||
# Targets built very early during a Gradle build.
|
||||
gradle-targets: .aapt.deps
|
||||
gradle-targets: $(foreach f,$(constants_PP_JAVAFILES),$(f))
|
||||
gradle-targets: $(abspath AndroidManifest.xml)
|
||||
gradle-targets: $(ANDROID_GENERATED_RESFILES)
|
||||
|
||||
gradle-omnijar: $(abspath $(DIST)/fennec/$(OMNIJAR_NAME))
|
||||
|
||||
|
|
|
@ -817,6 +817,7 @@ ANDROID_RES_DIRS += [
|
|||
]
|
||||
|
||||
ANDROID_GENERATED_RESFILES += [
|
||||
'res/raw/browsersearch.json',
|
||||
'res/raw/suggestedsites.json',
|
||||
'res/values/strings.xml',
|
||||
]
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- 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/. -->
|
||||
|
||||
<org.mozilla.gecko.tabs.TabPanelBackButton xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:gecko="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/nav_back"
|
||||
android:layout_width="@dimen/tabs_panel_button_width"
|
||||
android:layout_height="match_parent"
|
||||
android:minWidth="@dimen/tabs_panel_button_width"
|
||||
android:src="@drawable/tabs_panel_nav_back"
|
||||
android:contentDescription="@string/back"
|
||||
android:background="@drawable/action_bar_button_inverse"
|
||||
gecko:dividerVerticalPadding="@dimen/tab_panel_divider_vertical_padding"
|
||||
gecko:rightDivider="@drawable/tab_indicator_divider"/>
|
||||
|
|
@ -18,10 +18,16 @@
|
|||
android:layout_height="@dimen/browser_toolbar_height"
|
||||
android:background="@color/text_and_tabs_tray_grey">
|
||||
|
||||
<ViewStub android:id="@+id/nav_back_stub"
|
||||
android:layout="@layout/tabs_panel_back_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"/>
|
||||
<org.mozilla.gecko.tabs.TabPanelBackButton
|
||||
android:id="@+id/nav_back"
|
||||
android:layout_width="@dimen/tabs_panel_button_width"
|
||||
android:layout_height="match_parent"
|
||||
android:minWidth="@dimen/tabs_panel_button_width"
|
||||
android:src="@drawable/tabs_panel_nav_back"
|
||||
android:contentDescription="@string/back"
|
||||
android:background="@drawable/action_bar_button_inverse"
|
||||
gecko:dividerVerticalPadding="@dimen/tab_panel_divider_vertical_padding"
|
||||
gecko:rightDivider="@drawable/tab_indicator_divider"/>
|
||||
|
||||
<org.mozilla.gecko.widget.IconTabWidget android:id="@+id/tab_widget"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -96,9 +96,7 @@ public class TabsLayoutItemView extends LinearLayout
|
|||
mCloseButton = (ImageView) findViewById(R.id.close);
|
||||
mThumbnailWrapper = (TabThumbnailWrapper) findViewById(R.id.wrapper);
|
||||
|
||||
if (HardwareUtils.isTablet() || AppConstants.NIGHTLY_BUILD) {
|
||||
growCloseButtonHitArea();
|
||||
}
|
||||
growCloseButtonHitArea();
|
||||
}
|
||||
|
||||
private void growCloseButtonHitArea() {
|
||||
|
|
|
@ -164,16 +164,13 @@ public class TabsPanel extends LinearLayout
|
|||
}
|
||||
});
|
||||
|
||||
if (AppConstants.NIGHTLY_BUILD || HardwareUtils.isTablet()) {
|
||||
ViewStub backButtonStub = (ViewStub) findViewById(R.id.nav_back_stub);
|
||||
mNavBackButton = (ImageButton) backButtonStub.inflate( );
|
||||
mNavBackButton.setOnClickListener(new Button.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mActivity.onBackPressed();
|
||||
}
|
||||
});
|
||||
}
|
||||
mNavBackButton = (ImageButton) findViewById(R.id.nav_back);
|
||||
mNavBackButton.setOnClickListener(new Button.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mActivity.onBackPressed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void showMenu() {
|
||||
|
@ -249,39 +246,12 @@ public class TabsPanel extends LinearLayout
|
|||
}
|
||||
|
||||
private static int getTabContainerHeight(TabsLayoutContainer tabsContainer) {
|
||||
Resources resources = tabsContainer.getContext().getResources();
|
||||
final Resources resources = tabsContainer.getContext().getResources();
|
||||
|
||||
int screenHeight = resources.getDisplayMetrics().heightPixels;
|
||||
|
||||
int actionBarHeight = resources.getDimensionPixelSize(R.dimen.browser_toolbar_height);
|
||||
|
||||
if (HardwareUtils.isTablet() || AppConstants.NIGHTLY_BUILD) {
|
||||
return screenHeight - actionBarHeight;
|
||||
}
|
||||
|
||||
PanelView panelView = tabsContainer.getCurrentPanelView();
|
||||
if (panelView != null && !panelView.shouldExpand()) {
|
||||
|
||||
// This allows us to accommodate varying height tab previews across different devices.
|
||||
// We should be able to remove once we remove the list view and remove the chrome again
|
||||
return resources.getDimensionPixelSize(R.dimen.tab_thumbnail_height)
|
||||
+ resources.getDimensionPixelSize(R.dimen.tab_title_height)
|
||||
+ 2 * (resources.getDimensionPixelSize(R.dimen.tab_highlight_stroke_width)
|
||||
+ resources.getDimensionPixelSize(R.dimen.tab_vertical_padding)
|
||||
+ resources.getDimensionPixelSize(R.dimen.tab_thumbnail_padding)
|
||||
+ resources.getDimensionPixelSize(R.dimen.tab_thumbnail_margin));
|
||||
}
|
||||
|
||||
Rect windowRect = new Rect();
|
||||
tabsContainer.getWindowVisibleDisplayFrame(windowRect);
|
||||
int windowHeight = windowRect.bottom - windowRect.top;
|
||||
|
||||
// The web content area should have at least 1.5x the height of the action bar.
|
||||
// The tabs panel shouldn't take less than 50% of the screen height and can take
|
||||
// up to 80% of the window height.
|
||||
return (int) Math.max(screenHeight * 0.5f,
|
||||
Math.min(windowHeight - 2.5f * actionBarHeight, windowHeight * 0.8f) - actionBarHeight);
|
||||
final int screenHeight = resources.getDisplayMetrics().heightPixels;
|
||||
final int actionBarHeight = resources.getDimensionPixelSize(R.dimen.browser_toolbar_height);
|
||||
|
||||
return screenHeight - actionBarHeight;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
package org.mozilla.gecko.tabs;
|
||||
|
||||
import org.mozilla.gecko.AppConstants;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.ThumbnailHelper;
|
||||
import org.mozilla.gecko.widget.CropImageView;
|
||||
|
@ -35,11 +34,7 @@ public class TabsPanelThumbnailView extends CropImageView {
|
|||
|
||||
@Override
|
||||
protected float getAspectRatio() {
|
||||
if (AppConstants.NIGHTLY_BUILD) {
|
||||
return ThumbnailHelper.TABS_PANEL_THUMBNAIL_ASPECT_RATIO;
|
||||
} else {
|
||||
return ThumbnailHelper.TOP_SITES_THUMBNAIL_ASPECT_RATIO;
|
||||
}
|
||||
return ThumbnailHelper.TABS_PANEL_THUMBNAIL_ASPECT_RATIO;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1318,6 +1318,7 @@ var BrowserApp = {
|
|||
* @return the tab with the given URL, or null if no such tab exists
|
||||
*/
|
||||
getTabWithURL: function getTabWithURL(aURL, aOptions) {
|
||||
aOptions = aOptions || {};
|
||||
let uri = Services.io.newURI(aURL, null, null);
|
||||
for (let i = 0; i < this._tabs.length; ++i) {
|
||||
let tab = this._tabs[i];
|
||||
|
|
|
@ -7,6 +7,9 @@ android {
|
|||
defaultConfig {
|
||||
targetSdkVersion 22
|
||||
minSdkVersion 9
|
||||
applicationId mozconfig.substs.ANDROID_PACKAGE_NAME
|
||||
testApplicationId 'org.mozilla.roboexample.test'
|
||||
testInstrumentationRunner 'org.mozilla.gecko.FennecInstrumentationTestRunner'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
|
@ -25,13 +28,13 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
testApplicationId 'org.mozilla.roboexample.test'
|
||||
testInstrumentationRunner 'org.mozilla.gecko.FennecInstrumentationTestRunner'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile "${topobjdir}/mobile/android/base/AndroidManifest.xml"
|
||||
}
|
||||
|
||||
androidTest {
|
||||
manifest.srcFile "${topobjdir}/build/mobile/robocop/AndroidManifest.xml"
|
||||
java {
|
||||
srcDir "src/robocop_harness"
|
||||
srcDir "src/robocop"
|
||||
|
|
|
@ -46,11 +46,18 @@ android {
|
|||
srcDir 'src/webrtc_video_render'
|
||||
}
|
||||
|
||||
// Adjust helpers are included in the preprocessed_code project.
|
||||
exclude 'org/mozilla/gecko/adjust/**'
|
||||
if (mozconfig.substs.MOZ_INSTALL_TRACKING) {
|
||||
exclude 'org/mozilla/gecko/adjust/StubAdjustHelper.java'
|
||||
} else {
|
||||
exclude 'org/mozilla/gecko/adjust/AdjustHelper.java'
|
||||
}
|
||||
|
||||
srcDir "${project.buildDir}/generated/source/preprocessed_code" // See syncPreprocessedCode.
|
||||
}
|
||||
|
||||
res {
|
||||
srcDir "src/branding/res"
|
||||
srcDir "${project.buildDir}/generated/source/preprocessed_resources" // See syncPreprocessedResources.
|
||||
if (mozconfig.substs.MOZ_CRASHREPORTER) {
|
||||
srcDir "src/crashreporter/res"
|
||||
}
|
||||
|
@ -69,6 +76,22 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
task syncPreprocessedCode(type: Sync, dependsOn: rootProject.generateCodeAndResources) {
|
||||
into("${project.buildDir}/generated/source/preprocessed_code")
|
||||
from("${topobjdir}/mobile/android/base/generated/preprocessed")
|
||||
}
|
||||
|
||||
task syncPreprocessedResources(type: Sync, dependsOn: rootProject.generateCodeAndResources) {
|
||||
into("${project.buildDir}/generated/source/preprocessed_resources")
|
||||
from("${topobjdir}/mobile/android/base/res")
|
||||
}
|
||||
|
||||
android.libraryVariants.all { variant ->
|
||||
variant.preBuild.dependsOn syncPreprocessedCode
|
||||
variant.preBuild.dependsOn syncPreprocessedResources
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.android.support:support-v4:23.0.1'
|
||||
compile 'com.android.support:appcompat-v7:23.0.1'
|
||||
|
@ -81,11 +104,12 @@ dependencies {
|
|||
compile 'com.google.android.gms:play-services-cast:8.1.0'
|
||||
}
|
||||
|
||||
compile project(':branding')
|
||||
compile project(':preprocessed_code')
|
||||
compile project(':preprocessed_resources')
|
||||
compile project(':thirdparty')
|
||||
|
||||
if (mozconfig.substs.MOZ_INSTALL_TRACKING) {
|
||||
compile project(':thirdparty_adjust_sdk')
|
||||
}
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.robolectric:robolectric:3.0'
|
||||
testCompile 'org.simpleframework:simple-http:4.1.13'
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.mozilla.gecko.branding">
|
||||
|
||||
</manifest>
|
|
@ -1,20 +0,0 @@
|
|||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.1"
|
||||
|
||||
defaultConfig {
|
||||
targetSdkVersion 22
|
||||
minSdkVersion 9
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
|
@ -82,10 +82,10 @@ afterEvaluate {
|
|||
return
|
||||
}
|
||||
android.applicationVariants.all {
|
||||
checkManifest.dependsOn rootProject.generateCodeAndResources
|
||||
preBuild.dependsOn rootProject.generateCodeAndResources
|
||||
}
|
||||
android.libraryVariants.all {
|
||||
checkManifest.dependsOn rootProject.generateCodeAndResources
|
||||
preBuild.dependsOn rootProject.generateCodeAndResources
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,3 +97,6 @@ idea {
|
|||
languageLevel = '1.7'
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
}
|
||||
|
|
Двоичный файл не отображается.
|
@ -1,6 +1,6 @@
|
|||
#Sun Dec 21 20:16:49 PST 2014
|
||||
#Sun Oct 18 17:00:46 PDT 2015
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-bin.zip
|
||||
|
|
|
@ -42,11 +42,6 @@ case "`uname`" in
|
|||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
|
@ -114,6 +109,7 @@ fi
|
|||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.mozilla.gecko.preprocessed_code">
|
||||
|
||||
</manifest>
|
|
@ -1,53 +0,0 @@
|
|||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.1"
|
||||
|
||||
defaultConfig {
|
||||
targetSdkVersion 22
|
||||
minSdkVersion 9
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDir "${project.buildDir}/generated/source/java"
|
||||
|
||||
srcDir 'src/adjust/java'
|
||||
if (mozconfig.substs.MOZ_INSTALL_TRACKING) {
|
||||
exclude 'org/mozilla/gecko/adjust/StubAdjustHelper.java'
|
||||
} else {
|
||||
exclude 'org/mozilla/gecko/adjust/AdjustHelper.java'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task syncGeneratedSources(type: Sync) {
|
||||
into("${project.buildDir}/generated/source/java")
|
||||
from("${topobjdir}/mobile/android/base/generated/preprocessed")
|
||||
}
|
||||
|
||||
android.libraryVariants.all { variant ->
|
||||
// variant does not expose its generate sources task.
|
||||
def name = variant.buildType.name
|
||||
def generateSourcesTask = tasks.findByName("generate${name.capitalize()}Sources")
|
||||
generateSourcesTask.dependsOn syncGeneratedSources
|
||||
}
|
||||
|
||||
dependencies {
|
||||
if (mozconfig.substs.MOZ_INSTALL_TRACKING) {
|
||||
compile project(':thirdparty_adjust_sdk')
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.mozilla.gecko.preprocessed_resources">
|
||||
|
||||
</manifest>
|
|
@ -1,44 +0,0 @@
|
|||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.1"
|
||||
|
||||
defaultConfig {
|
||||
targetSdkVersion 22
|
||||
minSdkVersion 9
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
res {
|
||||
srcDir "${project.buildDir}/generated/source/preprocessed_resources"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task syncPreprocessedResources(type: Sync) {
|
||||
into("${project.buildDir}/generated/source/preprocessed_resources")
|
||||
from("${topobjdir}/mobile/android/base/res")
|
||||
}
|
||||
|
||||
android.libraryVariants.all { variant ->
|
||||
// variant does not expose its generate debug res values task.
|
||||
def name = variant.buildType.name
|
||||
def generateResValuesTask = tasks.findByName("generate${name.capitalize()}ResValues")
|
||||
generateResValuesTask.dependsOn syncPreprocessedResources
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':branding')
|
||||
}
|
|
@ -25,19 +25,13 @@ def json = slurper.parseText(standardOutput.toString())
|
|||
|
||||
include ':app'
|
||||
include ':base'
|
||||
include ':branding'
|
||||
include ':omnijar'
|
||||
include ':preprocessed_code'
|
||||
include ':preprocessed_resources'
|
||||
include ':thirdparty'
|
||||
|
||||
def gradleRoot = new File("${json.topobjdir}/mobile/android/gradle")
|
||||
project(':app').projectDir = new File(gradleRoot, 'app')
|
||||
project(':base').projectDir = new File(gradleRoot, 'base')
|
||||
project(':branding').projectDir = new File(gradleRoot, 'branding')
|
||||
project(':omnijar').projectDir = new File(gradleRoot, 'omnijar')
|
||||
project(':preprocessed_code').projectDir = new File(gradleRoot, 'preprocessed_code')
|
||||
project(':preprocessed_resources').projectDir = new File(gradleRoot, 'preprocessed_resources')
|
||||
project(':thirdparty').projectDir = new File(gradleRoot, 'thirdparty')
|
||||
|
||||
if (json.substs.MOZ_INSTALL_TRACKING) {
|
||||
|
|
|
@ -80,9 +80,6 @@ class MachCommands(MachCommandBase):
|
|||
def srcdir(dst, src):
|
||||
m.add_symlink(os.path.join(self.topsrcdir, src), dst)
|
||||
|
||||
def objdir(dst, src):
|
||||
m.add_symlink(os.path.join(self.topobjdir, src), dst)
|
||||
|
||||
srcdir('build.gradle', 'mobile/android/gradle/build.gradle')
|
||||
srcdir('settings.gradle', 'mobile/android/gradle/settings.gradle')
|
||||
|
||||
|
@ -103,17 +100,6 @@ class MachCommands(MachCommandBase):
|
|||
defines=defines,
|
||||
deps=os.path.join(self.topobjdir, 'mobile/android/gradle/.deps/local.properties.pp'))
|
||||
|
||||
srcdir('branding/build.gradle', 'mobile/android/gradle/branding/build.gradle')
|
||||
srcdir('branding/src/main/AndroidManifest.xml', 'mobile/android/gradle/branding/AndroidManifest.xml')
|
||||
srcdir('branding/src/main/res', os.path.join(self.substs['MOZ_BRANDING_DIRECTORY'], 'res'))
|
||||
|
||||
srcdir('preprocessed_code/build.gradle', 'mobile/android/gradle/preprocessed_code/build.gradle')
|
||||
srcdir('preprocessed_code/src/main/AndroidManifest.xml', 'mobile/android/gradle/preprocessed_code/AndroidManifest.xml')
|
||||
srcdir('preprocessed_code/src/adjust/java/org/mozilla/gecko/adjust', 'mobile/android/base/adjust')
|
||||
|
||||
srcdir('preprocessed_resources/build.gradle', 'mobile/android/gradle/preprocessed_resources/build.gradle')
|
||||
srcdir('preprocessed_resources/src/main/AndroidManifest.xml', 'mobile/android/gradle/preprocessed_resources/AndroidManifest.xml')
|
||||
|
||||
srcdir('thirdparty/build.gradle', 'mobile/android/gradle/thirdparty/build.gradle')
|
||||
srcdir('thirdparty/src/main/AndroidManifest.xml', 'mobile/android/gradle/thirdparty/AndroidManifest.xml')
|
||||
srcdir('thirdparty/src/main/java', 'mobile/android/thirdparty')
|
||||
|
@ -129,8 +115,6 @@ class MachCommands(MachCommandBase):
|
|||
srcdir('omnijar/src/main/java/themes', 'mobile/android/themes')
|
||||
|
||||
srcdir('app/build.gradle', 'mobile/android/gradle/app/build.gradle')
|
||||
objdir('app/src/main/AndroidManifest.xml', 'mobile/android/base/AndroidManifest.xml')
|
||||
objdir('app/src/androidTest/AndroidManifest.xml', 'build/mobile/robocop/AndroidManifest.xml')
|
||||
srcdir('app/src/androidTest/res', 'build/mobile/robocop/res')
|
||||
srcdir('app/src/androidTest/assets', 'mobile/android/tests/browser/robocop/assets')
|
||||
# Test code.
|
||||
|
@ -155,6 +139,7 @@ class MachCommands(MachCommandBase):
|
|||
srcdir('base/src/main/res', 'mobile/android/base/resources')
|
||||
srcdir('base/src/main/assets', 'mobile/android/app/assets')
|
||||
srcdir('base/src/crashreporter/res', 'mobile/android/base/crashreporter/res')
|
||||
srcdir('base/src/branding/res', os.path.join(self.substs['MOZ_BRANDING_DIRECTORY'], 'res'))
|
||||
# JUnit 4 test code.
|
||||
srcdir('base/src/background_junit4', 'mobile/android/tests/background/junit4/src')
|
||||
srcdir('base/resources/background_junit4', 'mobile/android/tests/background/junit4/resources')
|
||||
|
|
|
@ -27,6 +27,7 @@ support-files =
|
|||
[test_reader_view.html]
|
||||
[test_resource_substitutions.html]
|
||||
[test_restricted_profiles.html]
|
||||
[test_selectoraddtab.html]
|
||||
[test_session_form_data.html]
|
||||
[test_shared_preferences.html]
|
||||
[test_simple_discovery.html]
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1216047
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1216047</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="head.js"></script>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
"use strict";
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Messaging.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
|
||||
function promiseTabEvent(container, eventType) {
|
||||
return new Promise((resolve) => {
|
||||
function handle(event) {
|
||||
info("Received event " + eventType + " from container");
|
||||
container.removeEventListener(eventType, handle, true);
|
||||
resolve(event);
|
||||
}
|
||||
|
||||
container.addEventListener(eventType, handle, true);
|
||||
info("Now waiting for " + eventType + " event from container");
|
||||
});
|
||||
}
|
||||
|
||||
// The chrome window
|
||||
let chromeWin;
|
||||
|
||||
// Track the <browser>s where the tests are happening
|
||||
let browserBlank;
|
||||
let browserTest;
|
||||
|
||||
const kTestPage = "http://mochi.test:8888/chrome/mobile/android/tests/browser/chrome/basic_article.html";
|
||||
|
||||
add_task(function* test_selectOrAdd() {
|
||||
chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let BrowserApp = chromeWin.BrowserApp;
|
||||
|
||||
SimpleTest.registerCleanupFunction(function() {
|
||||
BrowserApp.closeTab(BrowserApp.getTabForBrowser(browserBlank));
|
||||
BrowserApp.closeTab(BrowserApp.getTabForBrowser(browserTest));
|
||||
});
|
||||
|
||||
// Add a new tab with a blank page
|
||||
browserBlank = BrowserApp.addTab("about:blank", { selected: true, parentId: BrowserApp.selectedTab.id }).browser;
|
||||
|
||||
// Now, let's force the target browser to be added
|
||||
browserTest = BrowserApp.selectOrAddTab(kTestPage, { selected: true, parentId: BrowserApp.selectedTab.id }).browser;
|
||||
yield promiseBrowserEvent(browserTest, "DOMContentLoaded");
|
||||
|
||||
// Check that basic_article is now selected
|
||||
is(BrowserApp.selectedBrowser, browserTest, "Target browser is selected after being added.");
|
||||
|
||||
// Switch back to about:blank
|
||||
BrowserApp.selectTab(BrowserApp.getTabForBrowser(browserBlank));
|
||||
yield promiseTabEvent(BrowserApp.deck, "TabSelect");
|
||||
|
||||
// Check that about:blank is selected
|
||||
is(BrowserApp.selectedBrowser, browserBlank, "about:blank is selected.");
|
||||
|
||||
// Use selectOrAddTab to select the existing tab
|
||||
BrowserApp.selectOrAddTab(kTestPage, { selected: true, parentId: BrowserApp.selectedTab.id }).browser;
|
||||
yield promiseTabEvent(BrowserApp.deck, "TabSelect");
|
||||
|
||||
// Check that basic_article is now selected
|
||||
is(BrowserApp.selectedBrowser, browserTest, "Target browser is selected.");
|
||||
|
||||
// Switch back to about:blank
|
||||
BrowserApp.selectTab(BrowserApp.getTabForBrowser(browserBlank));
|
||||
yield promiseTabEvent(BrowserApp.deck, "TabSelect");
|
||||
|
||||
// Check that about:blank is selected
|
||||
is(BrowserApp.selectedBrowser, browserBlank, "about:blank is selected.");
|
||||
|
||||
// Use selectOrAddTab to select the existing tab using the startsWith flag
|
||||
BrowserApp.selectOrAddTab(kTestPage, { selected: true, parentId: BrowserApp.selectedTab.id }, { startsWith: kTestPage }).browser;
|
||||
yield promiseTabEvent(BrowserApp.deck, "TabSelect");
|
||||
|
||||
// Check that basic_article is now selected
|
||||
is(BrowserApp.selectedBrowser, browserTest, "Target browser is selected.");
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1216047">Mozilla Bug 1216047</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -10,8 +10,6 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
#define ALERTS_BUNDLE "chrome://alerts/locale/alert.properties"
|
||||
|
||||
/* static */
|
||||
bool
|
||||
nsAlertsUtils::IsActionablePrincipal(nsIPrincipal* aPrincipal)
|
||||
|
@ -21,35 +19,6 @@ nsAlertsUtils::IsActionablePrincipal(nsIPrincipal* aPrincipal)
|
|||
!aPrincipal->GetIsNullPrincipal();
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsAlertsUtils::GetSource(nsIPrincipal* aPrincipal, nsAString& aSource)
|
||||
{
|
||||
nsAutoString hostPort;
|
||||
GetSourceHostPort(aPrincipal, hostPort);
|
||||
if (hostPort.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIStringBundleService> stringService(
|
||||
mozilla::services::GetStringBundleService());
|
||||
if (!stringService) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIStringBundle> alertsBundle;
|
||||
if (NS_WARN_IF(NS_FAILED(stringService->CreateBundle(ALERTS_BUNDLE,
|
||||
getter_AddRefs(alertsBundle))))) {
|
||||
return;
|
||||
}
|
||||
const char16_t* params[1] = { hostPort.get() };
|
||||
nsXPIDLString result;
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
alertsBundle->FormatStringFromName(MOZ_UTF16("source.label"), params, 1,
|
||||
getter_Copies(result))))) {
|
||||
return;
|
||||
}
|
||||
aSource = result;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsAlertsUtils::GetSourceHostPort(nsIPrincipal* aPrincipal,
|
||||
|
|
|
@ -22,13 +22,6 @@ public:
|
|||
static bool
|
||||
IsActionablePrincipal(nsIPrincipal* aPrincipal);
|
||||
|
||||
/**
|
||||
* Sets |aSource| to the localized notification source string, or an empty
|
||||
* string if |aPrincipal| is not actionable.
|
||||
*/
|
||||
static void
|
||||
GetSource(nsIPrincipal* aPrincipal, nsAString& aSource);
|
||||
|
||||
/**
|
||||
* Sets |aHostPort| to the host and port from |aPrincipal|'s URI, or an
|
||||
* empty string if |aPrincipal| is not actionable.
|
||||
|
|
|
@ -145,7 +145,7 @@ nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString&
|
|||
nsCOMPtr<nsISupportsString> scriptableAlertSource (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
|
||||
NS_ENSURE_TRUE(scriptableAlertSource, NS_ERROR_FAILURE);
|
||||
nsAutoString source;
|
||||
nsAlertsUtils::GetSource(aPrincipal, source);
|
||||
nsAlertsUtils::GetSourceHostPort(aPrincipal, source);
|
||||
scriptableAlertSource->SetData(source);
|
||||
rv = argsArray->AppendElement(scriptableAlertSource);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -32,14 +32,28 @@ function prefillAlertInfo() {
|
|||
// arguments[7] --> lang
|
||||
// arguments[8] --> replaced alert window (nsIDOMWindow)
|
||||
// arguments[9] --> an optional callback listener (nsIObserver)
|
||||
// arguments[10] -> the localized alert source string
|
||||
// arguments[10] -> the nsIURI.hostPort of the origin, optional
|
||||
|
||||
switch (window.arguments.length) {
|
||||
default:
|
||||
case 11: {
|
||||
if (window.arguments[10]) {
|
||||
document.getElementById('alertBox').setAttribute('hasOrigin', true);
|
||||
document.getElementById('alertSourceLabel').setAttribute('value', window.arguments[10]);
|
||||
let alertBox = document.getElementById("alertBox");
|
||||
alertBox.setAttribute("hasOrigin", true);
|
||||
|
||||
let hostPort = window.arguments[10];
|
||||
const ALERT_BUNDLE = Services.strings.createBundle(
|
||||
"chrome://alerts/locale/alert.properties");
|
||||
let label = document.getElementById("alertSourceLabel");
|
||||
label.setAttribute("value",
|
||||
ALERT_BUNDLE.formatStringFromName("source.label",
|
||||
[hostPort],
|
||||
1));
|
||||
let disableForOrigin = document.getElementById("disableForOriginMenuItem");
|
||||
disableForOrigin.setAttribute("label",
|
||||
ALERT_BUNDLE.formatStringFromName("webActions.disableForOrigin.label",
|
||||
[hostPort],
|
||||
1));
|
||||
}
|
||||
}
|
||||
case 10:
|
||||
|
@ -217,6 +231,11 @@ function onAlertClick() {
|
|||
}
|
||||
}
|
||||
|
||||
function disableForOrigin() {
|
||||
gAlertListener.observe(null, "alertdisablecallback", gAlertCookie);
|
||||
onAlertClose();
|
||||
}
|
||||
|
||||
function onAlertClose() {
|
||||
let alertBox = document.getElementById("alertBox");
|
||||
if (alertBox.getAttribute("animate") == "true") {
|
||||
|
|
|
@ -43,7 +43,13 @@
|
|||
<spacer flex="1"/>
|
||||
<box id="alertFooter">
|
||||
<label id="alertSourceLabel" class="alertSource plain"/>
|
||||
<button type="menu" id="alertSettings" tooltiptext="&settings.label;"/>
|
||||
<button type="menu" id="alertSettings" tooltiptext="&settings.label;"
|
||||
onclick="event.stopPropagation();">
|
||||
<menupopup position="after_end">
|
||||
<menuitem id="disableForOriginMenuItem"
|
||||
oncommand="disableForOrigin();"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
</box>
|
||||
</vbox>
|
||||
</box>
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
closeButton.title = Close
|
||||
# LOCALIZATION NOTE(actionButton.label): Used as the button label to provide more actions on OS X notifications. OS X will truncate this if it's too long.
|
||||
actionButton.label = …
|
||||
webActions.disable.label = Disable notifications from this site
|
||||
# LOCALIZATION NOTE(webActions.disableForOrigin.label): %S is replaced
|
||||
# with the hostname origin of the notification.
|
||||
webActions.disableForOrigin.label = Disable notifications from %S
|
||||
|
||||
# LOCALIZATION NOTE(source.label): Used to show the URL of the site that
|
||||
# sent the notification (e.g., "via mozilla.org"). "%1$S" is the source host
|
||||
|
|
|
@ -65,7 +65,6 @@ label {
|
|||
border-width: 0;
|
||||
min-width: 0;
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/utilities.svg#utilities");
|
||||
visibility: hidden; /* Temporary until bug 1209602 or bug 1205172 is fixed. */
|
||||
}
|
||||
|
||||
#alertSettings:hover {
|
||||
|
@ -73,7 +72,7 @@ label {
|
|||
border-radius: 20px;
|
||||
}
|
||||
|
||||
#alertSettings["open"],
|
||||
#alertSettings[open],
|
||||
#alertSettings:hover:active {
|
||||
background-color: rgba(107,107,107,.4);
|
||||
}
|
||||
|
|
|
@ -245,8 +245,18 @@ OSXNotificationCenter::ShowAlertNotification(const nsAString & aImageUrl, const
|
|||
|
||||
nsAutoString hostPort;
|
||||
nsAlertsUtils::GetSourceHostPort(aPrincipal, hostPort);
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
nsCOMPtr<nsIStringBundleService> sbs = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
|
||||
nsresult rv = sbs->CreateBundle("chrome://alerts/locale/alert.properties", getter_AddRefs(bundle));
|
||||
|
||||
if (!hostPort.IsEmpty()) {
|
||||
notification.subtitle = nsCocoaUtils::ToNSString(hostPort);
|
||||
const char16_t* formatStrings[] = { hostPort.get() };
|
||||
nsXPIDLString notificationSource;
|
||||
bundle->FormatStringFromName(NS_LITERAL_STRING("source.label").get(),
|
||||
formatStrings,
|
||||
ArrayLength(formatStrings),
|
||||
getter_Copies(notificationSource));
|
||||
notification.subtitle = nsCocoaUtils::ToNSString(notificationSource);
|
||||
}
|
||||
|
||||
notification.informativeText = nsCocoaUtils::ToNSString(aAlertText);
|
||||
|
@ -255,17 +265,19 @@ OSXNotificationCenter::ShowAlertNotification(const nsAString & aImageUrl, const
|
|||
|
||||
// If this is not an application/extension alert, show additional actions dealing with permissions.
|
||||
if (nsAlertsUtils::IsActionablePrincipal(aPrincipal)) {
|
||||
nsCOMPtr<nsIStringBundleService> sbs = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
nsresult rv = sbs->CreateBundle("chrome://alerts/locale/alert.properties", getter_AddRefs(bundle));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsXPIDLString closeButtonTitle, actionButtonTitle, disableButtonTitle, settingsButtonTitle;
|
||||
bundle->GetStringFromName(NS_LITERAL_STRING("closeButton.title").get(),
|
||||
getter_Copies(closeButtonTitle));
|
||||
bundle->GetStringFromName(NS_LITERAL_STRING("actionButton.label").get(),
|
||||
getter_Copies(actionButtonTitle));
|
||||
bundle->GetStringFromName(NS_LITERAL_STRING("webActions.disable.label").get(),
|
||||
getter_Copies(disableButtonTitle));
|
||||
if (!hostPort.IsEmpty()) {
|
||||
const char16_t* formatStrings[] = { hostPort.get() };
|
||||
bundle->FormatStringFromName(NS_LITERAL_STRING("webActions.disableForOrigin.label").get(),
|
||||
formatStrings,
|
||||
ArrayLength(formatStrings),
|
||||
getter_Copies(disableButtonTitle));
|
||||
}
|
||||
bundle->GetStringFromName(NS_LITERAL_STRING("webActions.settings.label").get(),
|
||||
getter_Copies(settingsButtonTitle));
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче