mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge fx-team to m-c.
This commit is contained in:
commit
212df74e79
@ -1102,6 +1102,9 @@ let RemoteDebugger = {
|
||||
"/data/local/debugger-socket";
|
||||
try {
|
||||
DebuggerServer.openListener(path);
|
||||
// Temporary event, until bug 942756 lands and offer a way to know
|
||||
// when the server is up and running
|
||||
Services.obs.notifyObservers(null, 'debugger-server-started', null);
|
||||
this._running = true;
|
||||
} catch (e) {
|
||||
dump('Unable to start debugger server: ' + e + '\n');
|
||||
|
@ -4631,6 +4631,7 @@
|
||||
role="presentation"
|
||||
layer="true" />
|
||||
<xul:image xbl:inherits="src=image,fadein,pinned,selected"
|
||||
anonid="tab-icon-image"
|
||||
class="tab-icon-image"
|
||||
validate="never"
|
||||
role="presentation"/>
|
||||
|
@ -52,7 +52,7 @@ add_task(function() {
|
||||
ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
|
||||
ok(CustomizableUI.inDefaultState, "Should start in default state.");
|
||||
|
||||
window.resizeTo(480, window.outerHeight);
|
||||
window.resizeTo(390, window.outerHeight);
|
||||
yield waitForCondition(() => navbar.hasAttribute("overflowing"));
|
||||
ok(!navbar.querySelector("#search-container"), "Search container should be overflowing");
|
||||
let searchbar = document.getElementById("searchbar");
|
||||
|
@ -13,7 +13,7 @@
|
||||
<overlay id="editBookmarkOverlay"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<vbox id="editBookmarkPanelContent">
|
||||
<vbox id="editBookmarkPanelContent" flex="1">
|
||||
<broadcaster id="paneElementsBroadcaster"/>
|
||||
|
||||
<hbox id="editBMPanel_selectionCount" hidden="true" pack="center">
|
||||
@ -107,13 +107,15 @@
|
||||
</hbox>
|
||||
</row>
|
||||
|
||||
<row align="center" id="editBMPanel_folderTreeRow" collapsed="true">
|
||||
<row id="editBMPanel_folderTreeRow" collapsed="true" flex="1">
|
||||
<spacer/>
|
||||
<vbox flex="1">
|
||||
<tree id="editBMPanel_folderTree"
|
||||
flex="1"
|
||||
class="placesTree"
|
||||
type="places"
|
||||
height="150"
|
||||
minheight="150"
|
||||
editable="true"
|
||||
onselect="gEditItemOverlay.onFolderTreeSelect();"
|
||||
hidecolumnpicker="true"
|
||||
|
@ -56,8 +56,10 @@ BrowserToolboxProcess.prototype = {
|
||||
// Create a separate loader instance, so that we can be sure to receive a
|
||||
// separate instance of the DebuggingServer from the rest of the devtools.
|
||||
// This allows us to safely use the tools against even the actors and
|
||||
// DebuggingServer itself.
|
||||
// DebuggingServer itself, especially since we can mark this loader as
|
||||
// invisible to the debugger (unlike the usual loader settings).
|
||||
this.loader = new DevToolsLoader();
|
||||
this.loader.invisibleToDebugger = true;
|
||||
this.loader.main("devtools/server/main");
|
||||
this.debuggerServer = this.loader.DebuggerServer;
|
||||
dumpn("Created a separate loader instance for the DebuggerServer.");
|
||||
|
@ -1268,9 +1268,6 @@ function MarkupContainer(aMarkupView, aNode, aInspector) {
|
||||
this._onMouseDown = this._onMouseDown.bind(this);
|
||||
this.elt.addEventListener("mousedown", this._onMouseDown, false);
|
||||
|
||||
this._onClick = this._onClick.bind(this);
|
||||
this.elt.addEventListener("click", this._onClick, false);
|
||||
|
||||
// Prepare the image preview tooltip data if any
|
||||
this._prepareImagePreview();
|
||||
}
|
||||
@ -1394,16 +1391,9 @@ MarkupContainer.prototype = {
|
||||
},
|
||||
|
||||
_onMouseDown: function(event) {
|
||||
if (event.target.nodeName !== "a") {
|
||||
this.hovered = false;
|
||||
this.markup.navigate(this);
|
||||
event.stopPropagation();
|
||||
}
|
||||
},
|
||||
|
||||
_onClick: function(event) {
|
||||
let target = event.target;
|
||||
|
||||
// Target may be a resource link (generated by the output-parser)
|
||||
if (target.nodeName === "a") {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
@ -1411,6 +1401,13 @@ MarkupContainer.prototype = {
|
||||
.tab.ownerDocument.defaultView;
|
||||
browserWin.openUILinkIn(target.href, "tab");
|
||||
}
|
||||
// Or it may be the "show more nodes" button (which already has its onclick)
|
||||
// Else, it's the container itself
|
||||
else if (target.nodeName !== "button") {
|
||||
this.hovered = false;
|
||||
this.markup.navigate(this);
|
||||
event.stopPropagation();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1544,7 +1541,11 @@ MarkupContainer.prototype = {
|
||||
// Recursively destroy children containers
|
||||
let firstChild;
|
||||
while (firstChild = this.children.firstChild) {
|
||||
firstChild.container.destroy();
|
||||
// Not all children of a container are containers themselves
|
||||
// ("show more nodes" button is one example)
|
||||
if (firstChild.container) {
|
||||
firstChild.container.destroy();
|
||||
}
|
||||
this.children.removeChild(firstChild);
|
||||
}
|
||||
|
||||
@ -1553,7 +1554,6 @@ MarkupContainer.prototype = {
|
||||
this.elt.removeEventListener("mouseover", this._onMouseOver, false);
|
||||
this.elt.removeEventListener("mouseout", this._onMouseOut, false);
|
||||
this.elt.removeEventListener("mousedown", this._onMouseDown, false);
|
||||
this.elt.removeEventListener("click", this._onClick, false);
|
||||
this.expander.removeEventListener("click", this._onToggle, false);
|
||||
|
||||
// Destroy my editor
|
||||
|
@ -6,6 +6,7 @@ support-files =
|
||||
browser_inspector_markup_navigation.html
|
||||
browser_inspector_markup_subset.html
|
||||
browser_inspector_markup_765105_tooltip.png
|
||||
browser_inspector_markup_950732.html
|
||||
head.js
|
||||
|
||||
[browser_bug896181_css_mixed_completion_new_attribute.js]
|
||||
@ -19,3 +20,4 @@ skip-if = true
|
||||
[browser_inspector_markup_navigation.js]
|
||||
[browser_inspector_markup_subset.js]
|
||||
[browser_inspector_markup_765105_tooltip.js]
|
||||
[browser_inspector_markup_950732.js]
|
||||
|
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html class="html">
|
||||
<body class="body">
|
||||
<ul>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
<li>some content</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,105 @@
|
||||
/* Any copyright", " is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the markup view loads only as many nodes as specified
|
||||
* by the devtools.markup.pagesize preference.
|
||||
*/
|
||||
|
||||
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
let promise = devtools.require("sdk/core/promise");
|
||||
let {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||
|
||||
// Make sure nodes are hidden when there are more than 5 in a row
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.clearUserPref("devtools.markup.pagesize");
|
||||
});
|
||||
Services.prefs.setIntPref("devtools.markup.pagesize", 5);
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let doc;
|
||||
let inspector;
|
||||
let markup;
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
doc = content.document;
|
||||
waitForFocus(runTests, content);
|
||||
}, true);
|
||||
content.location = "http://mochi.test:8888/browser/browser/devtools/markupview/test/browser_inspector_markup_950732.html";
|
||||
|
||||
function runTests() {
|
||||
Task.spawn(function() {
|
||||
yield openMarkupView();
|
||||
yield selectUL();
|
||||
yield reloadPage();
|
||||
yield showAllNodes();
|
||||
|
||||
assertAllNodesAreVisible();
|
||||
finishUp();
|
||||
}).then(null, Cu.reportError);
|
||||
}
|
||||
|
||||
function openMarkupView() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
var target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||
inspector = toolbox.getCurrentPanel();
|
||||
markup = inspector.markup;
|
||||
inspector.once("inspector-updated", deferred.resolve);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function selectUL() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let container = getContainerForRawNode(markup, doc.querySelector("ul"));
|
||||
let win = container.elt.ownerDocument.defaultView;
|
||||
|
||||
EventUtils.sendMouseEvent({type: "mousedown"}, container.elt, win);
|
||||
inspector.once("inspector-updated", deferred.resolve);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function reloadPage() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
inspector.once("new-root", () => {
|
||||
doc = content.document;
|
||||
markup = inspector.markup;
|
||||
markup._waitForChildren().then(deferred.resolve);
|
||||
});
|
||||
content.location.reload();
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function showAllNodes() {
|
||||
let container = getContainerForRawNode(markup, doc.querySelector("ul"));
|
||||
let button = container.elt.querySelector("button");
|
||||
let win = button.ownerDocument.defaultView;
|
||||
|
||||
EventUtils.sendMouseEvent({type: "click"}, button, win);
|
||||
return markup._waitForChildren();
|
||||
}
|
||||
|
||||
function assertAllNodesAreVisible() {
|
||||
let ul = doc.querySelector("ul");
|
||||
let container = getContainerForRawNode(markup, ul);
|
||||
ok(!container.elt.querySelector("button"), "All nodes button isn't here");
|
||||
is(container.children.childNodes.length, ul.children.length);
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
doc = inspector = markup = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
@ -132,7 +132,10 @@ function test() {
|
||||
// Make sure that clicking the "more" button loads all the nodes.
|
||||
let container = getContainerForRawNode(markup, doc.querySelector("body"));
|
||||
let button = container.elt.querySelector("button");
|
||||
button.click();
|
||||
let win = button.ownerDocument.defaultView;
|
||||
|
||||
EventUtils.sendMouseEvent({type: "click"}, button, win);
|
||||
|
||||
markup._waitForChildren().then(() => {
|
||||
assertChildren("abcdefghijklmnopqrstuvwxyz");
|
||||
finishUp();
|
||||
|
@ -26,9 +26,10 @@ var StartUI = {
|
||||
document.getElementById("bcast_preciseInput").setAttribute("input",
|
||||
this.chromeWin.InputSourceHelper.isPrecise ? "precise" : "imprecise");
|
||||
|
||||
// NOTE: location.search doesn't work for about: pages
|
||||
if (location.href.indexOf("?firstrun") > 0) {
|
||||
let firstRunCount = Services.prefs.getIntPref("browser.firstrun.count");
|
||||
if (firstRunCount > 0) {
|
||||
document.loadOverlay("chrome://browser/content/FirstRunOverlay.xul", null);
|
||||
Services.prefs.setIntPref("browser.firstrun.count", firstRunCount - 1);
|
||||
}
|
||||
|
||||
this._adjustDOMforViewState(this.chromeWin.ContentAreaObserver.viewstate);
|
||||
|
@ -222,11 +222,6 @@ BrowserCLH.prototype = {
|
||||
// Default to the saved homepage
|
||||
let defaultURL = getHomePage();
|
||||
|
||||
// Show page for first run or upgrade.
|
||||
if (needHomepageOverride() == "new profile") {
|
||||
defaultURL = 'about:newtab?firstrun';
|
||||
}
|
||||
|
||||
// Override the default if we have a URL passed on command line
|
||||
if (uris.length > 0) {
|
||||
defaultURL = uris[0].spec;
|
||||
|
@ -121,6 +121,9 @@ pref("browser.display.history.maxresults", 100);
|
||||
/* max items per section of the startui */
|
||||
pref("browser.display.startUI.maxresults", 16);
|
||||
|
||||
// Number of times to display firstrun instructions on new tab page
|
||||
pref("browser.firstrun.count", 3);
|
||||
|
||||
// Backspace and Shift+Backspace behavior
|
||||
// 0 goes Back/Forward
|
||||
// 1 act like PgUp/PgDown
|
||||
|
@ -57,7 +57,8 @@
|
||||
#tabs > .tabs-scrollbox > .scrollbutton-up {
|
||||
list-style-image: url("images/tab-arrows.png") !important;
|
||||
-moz-image-region: rect(15px 58px 63px 14px) !important;
|
||||
padding-right: 13px;
|
||||
padding-right: 15px;
|
||||
width: @tabs_scrollarrow_width@;
|
||||
}
|
||||
#tabs > .tabs-scrollbox > .scrollbutton-up:hover {
|
||||
-moz-image-region: rect(14px 102px 62px 58px) !important;
|
||||
@ -72,7 +73,8 @@
|
||||
#tabs > .tabs-scrollbox > .scrollbutton-down {
|
||||
list-style-image: url("images/tab-arrows.png") !important;
|
||||
-moz-image-region: rect(73px 58px 121px 14px) !important;
|
||||
padding-left: 16px;
|
||||
padding-left: 15px;
|
||||
width: @tabs_scrollarrow_width@;
|
||||
}
|
||||
#tabs > .tabs-scrollbox > .scrollbutton-down:hover {
|
||||
-moz-image-region: rect(72px 102px 120px 58px) !important;
|
||||
@ -84,6 +86,30 @@
|
||||
-moz-image-region: rect(73px 196px 121px 152px) !important;
|
||||
}
|
||||
|
||||
.tabs-scrollbox > .scrollbutton-up:not([disabled]):not([collapsed])::after {
|
||||
content: "";
|
||||
visibility: visible;
|
||||
display: block;
|
||||
background-color: rgb(90, 91, 95);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: calc(@tabs_scrollarrow_width@ + @metro_spacing_normal@); /* .scrollbutton-up width + #tabs-container left padding */
|
||||
width: 1px;
|
||||
height: @tabs_height@;
|
||||
}
|
||||
|
||||
.tabs-scrollbox > .scrollbutton-down:not([disabled]):not([collapsed])::before {
|
||||
content: "";
|
||||
visibility: visible;
|
||||
display: block;
|
||||
background-color: rgb(90, 91, 95);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: calc(@tabs_scrollarrow_width@ + @newtab_button_width@); /* .scrollbutton-down width + #newtab-button width */
|
||||
width: 1px;
|
||||
height: @tabs_height@;
|
||||
}
|
||||
|
||||
#tabs-container[viewstate="snapped"] {
|
||||
visibility: hidden;
|
||||
}
|
||||
@ -185,6 +211,7 @@ documenttab[selected] .documenttab-selection {
|
||||
|
||||
/* Add some extra padding for a larger target */
|
||||
padding: 18px 20px 30px 20px;
|
||||
width: @newtab_button_width@;
|
||||
}
|
||||
|
||||
/* Start UI ----------------------------------------------------------------- */
|
||||
|
@ -27,6 +27,8 @@
|
||||
%define toolbar_height 69px
|
||||
%define labelled_toolbar_height 90px
|
||||
%define tabs_height 178px
|
||||
%define newtab_button_width 63px
|
||||
%define tabs_scrollarrow_width 64px
|
||||
%define findbar_height 54px
|
||||
|
||||
%define progress_height 5px
|
||||
|
@ -64,6 +64,18 @@ this.UITour = {
|
||||
},
|
||||
widgetName: "search-container",
|
||||
}],
|
||||
["selectedTabIcon", {
|
||||
query: (aDocument) => {
|
||||
let selectedtab = aDocument.defaultView.gBrowser.selectedTab;
|
||||
let element = aDocument.getAnonymousElementByAttribute(selectedtab,
|
||||
"anonid",
|
||||
"tab-icon-image");
|
||||
if (!element || !_isElementVisible(element)) {
|
||||
return null;
|
||||
}
|
||||
return element;
|
||||
},
|
||||
}],
|
||||
["urlbar", {
|
||||
query: "#urlbar",
|
||||
widgetName: "urlbar-container",
|
||||
@ -489,6 +501,10 @@ this.UITour = {
|
||||
highlighter.parentElement.openPopup(aTargetEl, "overlap", offsetX, offsetY);
|
||||
}
|
||||
|
||||
// Prevent showing a panel at an undefined position.
|
||||
if (!_isElementVisible(aTarget.node))
|
||||
return;
|
||||
|
||||
this._setAppMenuStateForAnnotation(aTarget.node.ownerDocument.defaultView, "highlight",
|
||||
this.targetIsInAppMenu(aTarget),
|
||||
showHighlightPanel.bind(this, aTarget.node));
|
||||
@ -527,6 +543,10 @@ this.UITour = {
|
||||
tooltip.openPopup(aAnchorEl, alignment);
|
||||
}
|
||||
|
||||
// Prevent showing a panel at an undefined position.
|
||||
if (!_isElementVisible(aAnchor.node))
|
||||
return;
|
||||
|
||||
this._setAppMenuStateForAnnotation(aAnchor.node.ownerDocument.defaultView, "info",
|
||||
this.targetIsInAppMenu(aAnchor),
|
||||
showInfoPanel.bind(this, aAnchor.node));
|
||||
@ -615,3 +635,8 @@ this.UITour = {
|
||||
aWindow.gBrowser.selectedTab = tab;
|
||||
},
|
||||
};
|
||||
|
||||
function _isElementVisible(aElement) {
|
||||
let targetStyle = aElement.ownerDocument.defaultView.getComputedStyle(aElement);
|
||||
return (targetStyle.display != "none" && targetStyle.visibility == "visible");
|
||||
}
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "mozJSComponentLoader.h"
|
||||
|
||||
@ -91,6 +92,21 @@ struct Paths {
|
||||
* the same as homeDir.
|
||||
*/
|
||||
nsString desktopDir;
|
||||
/**
|
||||
* The user's 'application data' directory.
|
||||
* Windows:
|
||||
* HOME = Documents and Settings\$USER\Application Data
|
||||
* UAppData = $HOME[\$vendor]\$name
|
||||
*
|
||||
* Unix:
|
||||
* HOME = ~
|
||||
* UAppData = $HOME/.[$vendor/]$name
|
||||
*
|
||||
* Mac:
|
||||
* HOME = ~
|
||||
* UAppData = $HOME/Library/Application Support/$name
|
||||
*/
|
||||
nsString userApplicationDataDir;
|
||||
|
||||
#if defined(XP_WIN)
|
||||
/**
|
||||
@ -123,6 +139,7 @@ struct Paths {
|
||||
localProfileDir.SetIsVoid(true);
|
||||
homeDir.SetIsVoid(true);
|
||||
desktopDir.SetIsVoid(true);
|
||||
userApplicationDataDir.SetIsVoid(true);
|
||||
|
||||
#if defined(XP_WIN)
|
||||
winAppDataDir.SetIsVoid(true);
|
||||
@ -218,7 +235,7 @@ nsresult InitOSFileConstants()
|
||||
|
||||
// Initialize paths->libDir
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = NS_GetSpecialDirectory("XpcomLib", getter_AddRefs(file));
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_XPCOM_LIBRARY_FILE, getter_AddRefs(file));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@ -262,6 +279,7 @@ nsresult InitOSFileConstants()
|
||||
GetPathToSpecialDir(NS_OS_TEMP_DIR, paths->tmpDir);
|
||||
GetPathToSpecialDir(NS_OS_HOME_DIR, paths->homeDir);
|
||||
GetPathToSpecialDir(NS_OS_DESKTOP_DIR, paths->desktopDir);
|
||||
GetPathToSpecialDir(XRE_USER_APP_DATA_DIR, paths->userApplicationDataDir);
|
||||
|
||||
#if defined(XP_WIN)
|
||||
GetPathToSpecialDir(NS_WIN_APPDATA_DIR, paths->winAppDataDir);
|
||||
@ -857,6 +875,10 @@ bool DefineOSFileConstants(JSContext *cx, JS::Handle<JSObject*> global)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetStringProperty(cx, objPath, "userApplicationDataDir", gPaths->userApplicationDataDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
if (!SetStringProperty(cx, objPath, "winAppDataDir", gPaths->winAppDataDir)) {
|
||||
return false;
|
||||
|
@ -64,6 +64,7 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
||||
private RenderContext mLastPageContext;
|
||||
private int mMaxTextureSize;
|
||||
private int mBackgroundColor;
|
||||
private int mOverscrollColor;
|
||||
|
||||
private long mLastFrameTime;
|
||||
private final CopyOnWriteArrayList<RenderTask> mTasks;
|
||||
@ -134,6 +135,7 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
||||
|
||||
public LayerRenderer(LayerView view) {
|
||||
mView = view;
|
||||
mOverscrollColor = view.getContext().getResources().getColor(R.color.background_normal);
|
||||
|
||||
Bitmap scrollbarImage = view.getScrollbarImage();
|
||||
IntSize size = new IntSize(scrollbarImage.getWidth(), scrollbarImage.getHeight());
|
||||
@ -587,6 +589,9 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
||||
|
||||
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
|
||||
|
||||
// Draw the overscroll background area as a solid color
|
||||
clear(mOverscrollColor);
|
||||
|
||||
// Update background color.
|
||||
mBackgroundColor = mView.getBackgroundColor();
|
||||
|
||||
|
@ -62,6 +62,23 @@ import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@code BrowserToolbar} is single entry point for users of the toolbar
|
||||
* subsystem i.e. this should be the only import outside the 'toolbar'
|
||||
* package.
|
||||
*
|
||||
* {@code BrowserToolbar} serves at the single event bus for all
|
||||
* sub-components in the toolbar. It tracks tab events and gecko messages
|
||||
* and update the state of its inner components accordingly.
|
||||
*
|
||||
* It has two states, display and edit, which are controlled by
|
||||
* ToolbarEditLayout and ToolbarDisplayLayout. In display state, the toolbar
|
||||
* displays the current state for the selected tab. In edit state, it shows
|
||||
* a text entry for searching bookmarks/history. {@code BrowserToolbar}
|
||||
* provides public API to enter, cancel, and commit the edit state as well
|
||||
* as a set of listeners to allow {@code BrowserToolbar} users to react
|
||||
* to state changes accordingly.
|
||||
*/
|
||||
public class BrowserToolbar extends GeckoRelativeLayout
|
||||
implements Tabs.OnTabsChangedListener,
|
||||
GeckoMenu.ActionItemBarPresenter,
|
||||
|
@ -47,17 +47,38 @@ import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@code ToolbarDisplayLayout} is the UI for when the toolbar is in
|
||||
* display state. It's used to display the state of the currently selected
|
||||
* tab. It should always be updated through a single entry point
|
||||
* (updateFromTab) and should never track any tab events or gecko messages
|
||||
* on its own to keep it as dumb as possible.
|
||||
*
|
||||
* The UI has two possible modes: progress and display which are triggered
|
||||
* when UpdateFlags.PROGRESS is used depending on the current tab state.
|
||||
* The progress mode is triggered when the tab is loading a page. Display mode
|
||||
* is used otherwise.
|
||||
*
|
||||
* {@code ToolbarDisplayLayout} is meant to be owned by {@code BrowserToolbar}
|
||||
* which is the main event bus for the toolbar subsystem.
|
||||
*/
|
||||
public class ToolbarDisplayLayout extends GeckoLinearLayout
|
||||
implements Animation.AnimationListener {
|
||||
|
||||
private static final String LOGTAG = "GeckoToolbarDisplayLayout";
|
||||
|
||||
// To be used with updateFromTab() to allow the caller
|
||||
// to give enough context for the requested state change.
|
||||
enum UpdateFlags {
|
||||
TITLE,
|
||||
FAVICON,
|
||||
PROGRESS,
|
||||
SITE_IDENTITY,
|
||||
PRIVATE_MODE,
|
||||
|
||||
// Disable any animation that might be
|
||||
// triggered from this state change. Mostly
|
||||
// used on tab switches, see BrowserToolbar.
|
||||
DISABLE_ANIMATIONS
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,12 @@ import android.view.View.OnFocusChangeListener;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
/**
|
||||
* {@code ToolbarEditLayout} is the UI for when the toolbar is in
|
||||
* edit state. It controls a text entry ({@code ToolbarEditText})
|
||||
* and its matching 'go' button which changes depending on the
|
||||
* current type of text in the entry.
|
||||
*/
|
||||
public class ToolbarEditLayout extends GeckoLinearLayout {
|
||||
|
||||
private final ToolbarEditText mEditText;
|
||||
|
@ -30,11 +30,20 @@ import android.view.View.OnKeyListener;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
/**
|
||||
* {@code ToolbarEditText} is the text entry used when the toolbar
|
||||
* is in edit state. It handles all the necessary input method machinery
|
||||
* as well as the tracking of different text types (empty, search, or url).
|
||||
* It's meant to be owned by {@code ToolbarEditLayout}.
|
||||
*/
|
||||
public class ToolbarEditText extends CustomEditText
|
||||
implements AutocompleteHandler {
|
||||
|
||||
private static final String LOGTAG = "GeckoToolbarEditText";
|
||||
|
||||
// Used to track the current type of content in the
|
||||
// text entry so that ToolbarEditLayout can update its
|
||||
// state accordingly.
|
||||
enum TextType {
|
||||
EMPTY,
|
||||
SEARCH_QUERY,
|
||||
|
@ -676,7 +676,6 @@
|
||||
"layout/generic/test/test_plugin_clipping.xhtml": "Bug 931116, b2g desktop specific, initial triage",
|
||||
"layout/generic/test/test_plugin_clipping2.xhtml": "Bug 931116, b2g desktop specific, initial triage",
|
||||
"layout/generic/test/test_plugin_clipping_table.xhtml": "Bug 931116, b2g desktop specific, initial triage",
|
||||
"layout/generic/test/test_plugin_clipping_transformed.xhtml": "Bug 931116, b2g desktop specific, initial triage",
|
||||
"toolkit/devtools/apps/tests/test_webapps_actor.html": "Bug 931116, b2g desktop specific, initial triage"
|
||||
"layout/generic/test/test_plugin_clipping_transformed.xhtml": "Bug 931116, b2g desktop specific, initial triage"
|
||||
}
|
||||
}
|
||||
|
@ -154,3 +154,7 @@ user_pref("browser.pagethumbnails.capturing_disabled", true);
|
||||
// Indicate that the download panel has been shown once so that whichever
|
||||
// download test runs first doesn't show the popup inconsistently.
|
||||
user_pref("browser.download.panel.shown", true);
|
||||
|
||||
// prefs for firefox metro.
|
||||
// Disable first-tun tab
|
||||
user_pref("browser.firstrun.count", 0);
|
||||
|
@ -37,6 +37,8 @@ add_task(function() {
|
||||
do_check_true(!!OS.Constants.Path.desktopDir);
|
||||
do_check_eq(OS.Constants.Path.desktopDir, Services.dirsvc.get("Desk", Components.interfaces.nsIFile).path);
|
||||
|
||||
compare_paths(OS.Constants.Path.userApplicationDataDir, "UAppData");
|
||||
|
||||
compare_paths(OS.Constants.Path.winAppDataDir, "AppData");
|
||||
compare_paths(OS.Constants.Path.winStartMenuProgsDir, "Progs");
|
||||
|
||||
|
@ -35,6 +35,7 @@ let loaderGlobals = {
|
||||
btoa: btoa,
|
||||
console: console,
|
||||
_Iterator: Iterator,
|
||||
ChromeWorker: ChromeWorker,
|
||||
loader: {
|
||||
lazyGetter: XPCOMUtils.defineLazyGetter.bind(XPCOMUtils),
|
||||
lazyImporter: XPCOMUtils.defineLazyModuleGetter.bind(XPCOMUtils),
|
||||
@ -43,7 +44,8 @@ let loaderGlobals = {
|
||||
};
|
||||
|
||||
// Used when the tools should be loaded from the Firefox package itself (the default)
|
||||
var BuiltinProvider = {
|
||||
function BuiltinProvider() {}
|
||||
BuiltinProvider.prototype = {
|
||||
load: function() {
|
||||
this.loader = new loader.Loader({
|
||||
modules: {
|
||||
@ -72,7 +74,8 @@ var BuiltinProvider = {
|
||||
// Allow access to xpcshell test items from the loader.
|
||||
"xpcshell-test": "resource://test"
|
||||
},
|
||||
globals: loaderGlobals
|
||||
globals: loaderGlobals,
|
||||
invisibleToDebugger: this.invisibleToDebugger
|
||||
});
|
||||
|
||||
return promise.resolve(undefined);
|
||||
@ -87,7 +90,8 @@ var BuiltinProvider = {
|
||||
// Used when the tools should be loaded from a mozilla-central checkout. In addition
|
||||
// to different paths, it needs to write chrome.manifest files to override chrome urls
|
||||
// from the builtin tools.
|
||||
var SrcdirProvider = {
|
||||
function SrcdirProvider() {}
|
||||
SrcdirProvider.prototype = {
|
||||
fileURI: function(path) {
|
||||
let file = new FileUtils.File(path);
|
||||
return Services.io.newFileURI(file).spec;
|
||||
@ -134,7 +138,8 @@ var SrcdirProvider = {
|
||||
"acorn": acornURI,
|
||||
"acorn_loose": acornLoosseURI
|
||||
},
|
||||
globals: loaderGlobals
|
||||
globals: loaderGlobals,
|
||||
invisibleToDebugger: this.invisibleToDebugger
|
||||
});
|
||||
|
||||
return this._writeManifest(devtoolsDir).then(null, Cu.reportError);
|
||||
@ -218,12 +223,29 @@ var SrcdirProvider = {
|
||||
* then a new one can also be created.
|
||||
*/
|
||||
this.DevToolsLoader = function DevToolsLoader() {
|
||||
this._chooseProvider();
|
||||
this.require = this.require.bind(this);
|
||||
};
|
||||
|
||||
DevToolsLoader.prototype = {
|
||||
get provider() {
|
||||
if (!this._provider) {
|
||||
this._chooseProvider();
|
||||
}
|
||||
return this._provider;
|
||||
},
|
||||
|
||||
_provider: null,
|
||||
|
||||
/**
|
||||
* A dummy version of require, in case a provider hasn't been chosen yet when
|
||||
* this is first called. This will then be replaced by the real version.
|
||||
* @see setProvider
|
||||
*/
|
||||
require: function() {
|
||||
this._chooseProvider();
|
||||
return this.require.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a URI to the loader.
|
||||
* @param string id
|
||||
@ -234,7 +256,7 @@ DevToolsLoader.prototype = {
|
||||
*/
|
||||
loadURI: function(id, uri) {
|
||||
let module = loader.Module(id, uri);
|
||||
return loader.load(this._provider.loader, module).exports;
|
||||
return loader.load(this.provider.loader, module).exports;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -248,7 +270,7 @@ DevToolsLoader.prototype = {
|
||||
*/
|
||||
main: function(id) {
|
||||
this._mainid = id;
|
||||
this._main = loader.main(this._provider.loader, id);
|
||||
this._main = loader.main(this.provider.loader, id);
|
||||
|
||||
// Mirror the main module's exports on this object.
|
||||
Object.getOwnPropertyNames(this._main).forEach(key => {
|
||||
@ -271,6 +293,7 @@ DevToolsLoader.prototype = {
|
||||
this._provider.unload("newprovider");
|
||||
}
|
||||
this._provider = provider;
|
||||
this._provider.invisibleToDebugger = this.invisibleToDebugger;
|
||||
this._provider.load();
|
||||
this.require = loader.Require(this._provider.loader, { id: "devtools" });
|
||||
|
||||
@ -284,9 +307,9 @@ DevToolsLoader.prototype = {
|
||||
*/
|
||||
_chooseProvider: function() {
|
||||
if (Services.prefs.prefHasUserValue("devtools.loader.srcdir")) {
|
||||
this.setProvider(SrcdirProvider);
|
||||
this.setProvider(new SrcdirProvider());
|
||||
} else {
|
||||
this.setProvider(BuiltinProvider);
|
||||
this.setProvider(new BuiltinProvider());
|
||||
}
|
||||
},
|
||||
|
||||
@ -302,6 +325,17 @@ DevToolsLoader.prototype = {
|
||||
delete this._provider;
|
||||
this._chooseProvider();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets whether the compartments loaded by this instance should be invisible
|
||||
* to the debugger. Invisibility is needed for loaders that support debugging
|
||||
* of chrome code. This is true of remote target environments, like Fennec or
|
||||
* B2G. It is not the default case for desktop Firefox because we offer the
|
||||
* Browser Toolbox for chrome debugging there, which uses its own, separate
|
||||
* loader instance.
|
||||
* @see browser/devtools/framework/ToolboxProcess.jsm
|
||||
*/
|
||||
invisibleToDebugger: Services.appinfo.name !== "Firefox"
|
||||
};
|
||||
|
||||
// Export the standard instance of DevToolsLoader used by the tools.
|
||||
|
@ -14,20 +14,36 @@ const { Services } = Cu.import("resource://gre/modules/Services.jsm");
|
||||
let gClient, gActor;
|
||||
|
||||
function connect(onDone) {
|
||||
// Initialize a loopback remote protocol connection
|
||||
DebuggerServer.init(function () { return true; });
|
||||
// We need to register browser actors to have `listTabs` working
|
||||
// and also have a root actor
|
||||
|
||||
if (Services.appinfo.name == "B2G") {
|
||||
DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/webbrowser.js");
|
||||
DebuggerServer.addActors('chrome://browser/content/dbg-browser-actors.js');
|
||||
DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/webapps.js");
|
||||
} else {
|
||||
// On b2g, we try to exercice the code that launches the production debugger server
|
||||
let settingsService = Cc["@mozilla.org/settingsService;1"].getService(Ci.nsISettingsService);
|
||||
settingsService.createLock().set("devtools.debugger.remote-enabled", true, null);
|
||||
// We can't use `set` callback as it is fired before shell.js code listening for this setting
|
||||
// is actually called. Same thing applies to mozsettings-changed obs notification.
|
||||
// So listen to a custom event until bug 942756 lands
|
||||
let observer = {
|
||||
observe: function (subject, topic, data) {
|
||||
Services.obs.removeObserver(observer, "debugger-server-started");
|
||||
let transport = debuggerSocketConnect("127.0.0.1", 6000);
|
||||
startClient(transport, onDone);
|
||||
}
|
||||
};
|
||||
Services.obs.addObserver(observer, "debugger-server-started", false);
|
||||
} else {
|
||||
// Initialize a loopback remote protocol connection
|
||||
DebuggerServer.init(function () { return true; });
|
||||
// We need to register browser actors to have `listTabs` working
|
||||
// and also have a root actor
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
startClient(transport, onDone);
|
||||
}
|
||||
}
|
||||
|
||||
function startClient(transport, onDone) {
|
||||
// Setup client and actor used in all tests
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect(function onConnect() {
|
||||
gClient.listTabs(function onListTabs(aResponse) {
|
||||
gActor = aResponse.webappsActor;
|
||||
|
@ -75,7 +75,9 @@ var steps = [
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [["dom.mozBrowserFramesEnabled", true],
|
||||
["security.apps.privileged.CSP.default",
|
||||
"default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'"]
|
||||
"default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'"],
|
||||
["devtools.debugger.unix-domain-socket", 6000],
|
||||
["devtools.debugger.prompt-connection", false]
|
||||
]
|
||||
}, next);
|
||||
},
|
||||
|
@ -5,10 +5,16 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
var Ci = Components.interfaces;
|
||||
var Cc = Components.classes;
|
||||
var Cu = Components.utils;
|
||||
var Cr = Components.results;
|
||||
// On B2G scope object misbehaves and we have to bind globals to `this`
|
||||
// in order to ensure theses variable to be visible in transport.js
|
||||
this.Ci = Ci;
|
||||
this.Cc = Cc;
|
||||
this.Cu = Cu;
|
||||
this.Cr = Cr;
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["DebuggerTransport",
|
||||
"DebuggerClient",
|
||||
|
@ -15,31 +15,11 @@ const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cu = Components.utils;
|
||||
|
||||
const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["DebuggerServer", "ActorPool"];
|
||||
|
||||
var loadSubScript =
|
||||
"function loadSubScript(aURL)\n" +
|
||||
"{\n" +
|
||||
"const Ci = Components.interfaces;\n" +
|
||||
"const Cc = Components.classes;\n" +
|
||||
" try {\n" +
|
||||
" let loader = Cc[\"@mozilla.org/moz/jssubscript-loader;1\"]\n" +
|
||||
" .getService(Ci.mozIJSSubScriptLoader);\n" +
|
||||
" loader.loadSubScript(aURL, this);\n" +
|
||||
" } catch(e) {\n" +
|
||||
" dump(\"Error loading: \" + aURL + \": \" + e + \" - \" + e.stack + \"\\n\");\n" +
|
||||
" throw e;\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
let server = devtools.require("devtools/server/main");
|
||||
|
||||
// Load the debugging server in a sandbox with its own compartment.
|
||||
var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"]
|
||||
.createInstance(Ci.nsIPrincipal);
|
||||
|
||||
var gGlobal = Cu.Sandbox(systemPrincipal);
|
||||
gGlobal.ChromeWorker = ChromeWorker;
|
||||
Cu.evalInSandbox(loadSubScript, gGlobal, "1.8");
|
||||
gGlobal.loadSubScript("resource://gre/modules/devtools/server/main.js");
|
||||
|
||||
this.DebuggerServer = gGlobal.DebuggerServer;
|
||||
this.ActorPool = gGlobal.ActorPool;
|
||||
this.DebuggerServer = server.DebuggerServer;
|
||||
this.ActorPool = server.ActorPool;
|
||||
|
@ -10,36 +10,22 @@
|
||||
* debugging global.
|
||||
*/
|
||||
|
||||
// |this.require| is used to test if this file was loaded via the devtools
|
||||
// loader (as it is in DebuggerProcess.jsm) or via loadSubScript (as it is from
|
||||
// dbg-server.jsm). Note that testing |require| is not safe in either
|
||||
// situation, as it causes a ReferenceError.
|
||||
var Ci, Cc, CC, Cu, Cr, Components;
|
||||
if (this.require) {
|
||||
({ Ci, Cc, CC, Cu, Cr, components: Components }) = require("chrome");
|
||||
} else {
|
||||
({
|
||||
interfaces: Ci,
|
||||
classes: Cc,
|
||||
Constructor: CC,
|
||||
utils: Cu,
|
||||
results: Cr
|
||||
}) = Components;
|
||||
}
|
||||
|
||||
// On B2G, if |this.require| is undefined at this point, it remains undefined
|
||||
// later on when |DebuggerServer.registerModule| is called. On desktop (and
|
||||
// perhaps other places), if |this.require| starts out undefined, it ends up
|
||||
// being set to some native code by the time we get to |registerModule|. Here
|
||||
// we perform a test early on, and then cache the correct require function for
|
||||
// later use.
|
||||
var localRequire;
|
||||
if (this.require) {
|
||||
localRequire = id => require(id);
|
||||
} else {
|
||||
let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
localRequire = id => devtools.require(id);
|
||||
}
|
||||
// Until all Debugger server code is converted to SDK modules,
|
||||
// imports Components.* alias from chrome module.
|
||||
var { Ci, Cc, CC, Cu, Cr } = require("chrome");
|
||||
// On B2G, `this` != Global scope, so `Ci` won't be binded on `this`
|
||||
// (i.e. this.Ci is undefined) Then later, when using loadSubScript,
|
||||
// Ci,... won't be defined for sub scripts.
|
||||
this.Ci = Ci;
|
||||
this.Cc = Cc;
|
||||
this.CC = CC;
|
||||
this.Cu = Cu;
|
||||
this.Cr = Cr;
|
||||
// Overload `Components` to prevent SDK loader exception on Components
|
||||
// object usage
|
||||
Object.defineProperty(this, "Components", {
|
||||
get: function () require("chrome").components
|
||||
});
|
||||
|
||||
const DBG_STRINGS_URI = "chrome://global/locale/devtools/debugger.properties";
|
||||
|
||||
@ -49,7 +35,6 @@ Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
let wantLogging = Services.prefs.getBoolPref("devtools.debugger.log");
|
||||
const promptConnections = Services.prefs.getBoolPref("devtools.debugger.prompt-connection");
|
||||
|
||||
Cu.import("resource://gre/modules/jsdebugger.jsm");
|
||||
addDebuggerToGlobal(this);
|
||||
@ -68,10 +53,12 @@ function loadSubScript(aURL)
|
||||
}
|
||||
}
|
||||
|
||||
let loaderRequire = this.require;
|
||||
this.require = null;
|
||||
loadSubScript.call(this, "resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
this.require = loaderRequire;
|
||||
let {defer, resolve, reject, promised, all} = require("sdk/core/promise");
|
||||
this.defer = defer;
|
||||
this.resolve = resolve;
|
||||
this.reject = reject;
|
||||
this.promised = promised;
|
||||
this.all = all;
|
||||
|
||||
Cu.import("resource://gre/modules/devtools/SourceMap.jsm");
|
||||
|
||||
@ -82,12 +69,14 @@ function dumpn(str) {
|
||||
dump("DBG-SERVER: " + str + "\n");
|
||||
}
|
||||
}
|
||||
this.dumpn = dumpn;
|
||||
|
||||
function dbg_assert(cond, e) {
|
||||
if (!cond) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
this.dbg_assert = dbg_assert;
|
||||
|
||||
loadSubScript.call(this, "resource://gre/modules/devtools/server/transport.js");
|
||||
|
||||
@ -324,7 +313,7 @@ var DebuggerServer = {
|
||||
}
|
||||
|
||||
let moduleAPI = ModuleAPI();
|
||||
let mod = localRequire(id);
|
||||
let mod = require(id);
|
||||
mod.register(moduleAPI);
|
||||
gRegisteredModules[id] = { module: mod, api: moduleAPI };
|
||||
},
|
||||
@ -523,7 +512,7 @@ var DebuggerServer = {
|
||||
|
||||
onSocketAccepted:
|
||||
makeInfallible(function DS_onSocketAccepted(aSocket, aTransport) {
|
||||
if (promptConnections && !this._allowConnection()) {
|
||||
if (Services.prefs.getBoolPref("devtools.debugger.prompt-connection") && !this._allowConnection()) {
|
||||
return;
|
||||
}
|
||||
dumpn("New debugging connection on " + aTransport.host + ":" + aTransport.port);
|
||||
@ -690,6 +679,8 @@ var DebuggerServer = {
|
||||
if (this.exports) {
|
||||
exports.DebuggerServer = DebuggerServer;
|
||||
}
|
||||
// Needed on B2G (See header note)
|
||||
this.DebuggerServer = DebuggerServer;
|
||||
|
||||
/**
|
||||
* Construct an ActorPool.
|
||||
@ -708,6 +699,8 @@ function ActorPool(aConnection)
|
||||
if (this.exports) {
|
||||
exports.ActorPool = ActorPool;
|
||||
}
|
||||
// Needed on B2G (See header note)
|
||||
this.ActorPool = ActorPool;
|
||||
|
||||
ActorPool.prototype = {
|
||||
/**
|
||||
|
@ -37,11 +37,13 @@
|
||||
const { BuiltinProvider, SrcdirProvider } =
|
||||
Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
|
||||
BuiltinProvider.load();
|
||||
SrcdirProvider.load();
|
||||
let builtin = new BuiltinProvider();
|
||||
builtin.load();
|
||||
let srcdir = new SrcdirProvider();
|
||||
srcdir.load();
|
||||
|
||||
is(BuiltinProvider.loader.mapping.length,
|
||||
SrcdirProvider.loader.mapping.length + 1,
|
||||
is(builtin.loader.mapping.length,
|
||||
srcdir.loader.mapping.length + 1,
|
||||
"The built-in loader should have only one more mapping for testing.");
|
||||
|
||||
Services.prefs.clearUserPref(SRCDIR_PREF);
|
||||
|
23
toolkit/devtools/tests/unit/test_independent_loaders.js
Normal file
23
toolkit/devtools/tests/unit/test_independent_loaders.js
Normal file
@ -0,0 +1,23 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const { DevToolsLoader } =
|
||||
Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
|
||||
/**
|
||||
* Ensure that each instance of the Dev Tools loader contains its own loader
|
||||
* instance, and also returns unique objects. This ensures there is no sharing
|
||||
* in place between loaders.
|
||||
*/
|
||||
function run_test() {
|
||||
let loader1 = new DevToolsLoader();
|
||||
let loader2 = new DevToolsLoader();
|
||||
|
||||
let color1 = loader1.require("devtools/css-color");
|
||||
let color2 = loader2.require("devtools/css-color");
|
||||
|
||||
do_check_true(color1 !== color2);
|
||||
|
||||
do_check_true(loader1._provider !== loader2._provider);
|
||||
do_check_true(loader1._provider.loader !== loader2._provider.loader);
|
||||
}
|
50
toolkit/devtools/tests/unit/test_invisible_loader.js
Normal file
50
toolkit/devtools/tests/unit/test_invisible_loader.js
Normal file
@ -0,0 +1,50 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const { DevToolsLoader } =
|
||||
Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
Cu.import("resource://gre/modules/jsdebugger.jsm");
|
||||
addDebuggerToGlobal(this);
|
||||
|
||||
const COLOR_URI = "resource://gre/modules/devtools/css-color.js";
|
||||
|
||||
/**
|
||||
* Ensure that sandboxes created via the Dev Tools loader respect the
|
||||
* invisibleToDebugger flag.
|
||||
*/
|
||||
function run_test() {
|
||||
visible_loader();
|
||||
invisible_loader();
|
||||
}
|
||||
|
||||
function visible_loader() {
|
||||
let loader = new DevToolsLoader();
|
||||
loader.invisibleToDebugger = false;
|
||||
loader.require("devtools/css-color");
|
||||
|
||||
let dbg = new Debugger();
|
||||
let sandbox = loader._provider.loader.sandboxes[COLOR_URI];
|
||||
|
||||
try {
|
||||
dbg.addDebuggee(sandbox);
|
||||
do_check_true(true);
|
||||
} catch(e) {
|
||||
do_throw("debugger could not add visible value");
|
||||
}
|
||||
}
|
||||
|
||||
function invisible_loader() {
|
||||
let loader = new DevToolsLoader();
|
||||
loader.invisibleToDebugger = true;
|
||||
loader.require("devtools/css-color");
|
||||
|
||||
let dbg = new Debugger();
|
||||
let sandbox = loader._provider.loader.sandboxes[COLOR_URI];
|
||||
|
||||
try {
|
||||
dbg.addDebuggee(sandbox);
|
||||
do_throw("debugger added invisible value");
|
||||
} catch(e) {
|
||||
do_check_true(true);
|
||||
}
|
||||
}
|
@ -2,5 +2,7 @@
|
||||
head = head_devtools.js
|
||||
tail =
|
||||
|
||||
[test_independent_loaders.js]
|
||||
[test_invisible_loader.js]
|
||||
[test_safeErrorString.js]
|
||||
[test_defineLazyPrototypeGetter.js]
|
||||
|
Loading…
Reference in New Issue
Block a user