зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
c00b38c806
|
@ -218,6 +218,7 @@
|
|||
hidden="true"
|
||||
noautofocus="true"
|
||||
noautohide="true"
|
||||
flip="none"
|
||||
consumeoutsideclicks="false">
|
||||
<box id="UITourHighlight"></box>
|
||||
</panel>
|
||||
|
|
|
@ -11,9 +11,9 @@ const {Cc, Ci, Cu} = require("chrome");
|
|||
let WebConsoleUtils = require("devtools/toolkit/webconsole/utils").Utils;
|
||||
let Heritage = require("sdk/core/heritage");
|
||||
|
||||
loader.lazyGetter(this, "promise", () => require("sdk/core/promise"));
|
||||
loader.lazyGetter(this, "Telemetry", () => require("devtools/shared/telemetry"));
|
||||
loader.lazyGetter(this, "WebConsoleFrame", () => require("devtools/webconsole/webconsole").WebConsoleFrame);
|
||||
loader.lazyImporter(this, "promise", "resource://gre/modules/Promise.jsm", "Promise");
|
||||
loader.lazyImporter(this, "gDevTools", "resource:///modules/devtools/gDevTools.jsm");
|
||||
loader.lazyImporter(this, "devtools", "resource://gre/modules/devtools/Loader.jsm");
|
||||
loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm");
|
||||
|
@ -110,6 +110,7 @@ HUD_SERVICE.prototype =
|
|||
function HS_openBrowserConsole(aTarget, aIframeWindow, aChromeWindow)
|
||||
{
|
||||
let hud = new BrowserConsole(aTarget, aIframeWindow, aChromeWindow);
|
||||
this._browserConsoleID = hud.hudId;
|
||||
this.consoles.set(hud.hudId, hud);
|
||||
return hud.init();
|
||||
},
|
||||
|
@ -241,7 +242,6 @@ HUD_SERVICE.prototype =
|
|||
connect().then(getTarget).then(openWindow).then((aWindow) => {
|
||||
this.openBrowserConsole(target, aWindow, aWindow)
|
||||
.then((aBrowserConsole) => {
|
||||
this._browserConsoleID = aBrowserConsole.hudId;
|
||||
this._browserConsoleDefer.resolve(aBrowserConsole);
|
||||
this._browserConsoleDefer = null;
|
||||
})
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
const {Cc, Ci, Cu} = require("chrome");
|
||||
|
||||
loader.lazyGetter(this, "promise", () => require("sdk/core/promise"));
|
||||
loader.lazyImporter(this, "promise", "resource://gre/modules/Promise.jsm", "Promise");
|
||||
loader.lazyGetter(this, "HUDService", () => require("devtools/webconsole/hudservice"));
|
||||
loader.lazyGetter(this, "EventEmitter", () => require("devtools/shared/event-emitter"));
|
||||
|
||||
|
|
|
@ -49,7 +49,10 @@ function test()
|
|||
EventUtils.synthesizeKey(c, {}, hud.iframeWindow);
|
||||
}
|
||||
|
||||
hud.jsterm.execute(null, onReadProperty.bind(null, msg));
|
||||
hud.jsterm.execute(null, () => {
|
||||
// executeSoon() is needed to get out of the execute() event loop.
|
||||
executeSoon(onReadProperty.bind(null, msg));
|
||||
});
|
||||
}
|
||||
|
||||
function onReadProperty(deadObjectMessage)
|
||||
|
@ -69,6 +72,7 @@ function test()
|
|||
|
||||
function onFetched()
|
||||
{
|
||||
ok(true, "variables view fetched");
|
||||
hud.jsterm.execute("delete window.foobarzTezt; 2013-26", onCalcResult);
|
||||
}
|
||||
|
||||
|
|
|
@ -95,35 +95,22 @@ function testGen() {
|
|||
testNext();
|
||||
};
|
||||
EventUtils.synthesizeKey("VK_END", {});
|
||||
yield;
|
||||
yield undefined;
|
||||
|
||||
let oldScrollTop = scrollBox.scrollTop;
|
||||
|
||||
content.console.log("test message 151");
|
||||
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "test message 151",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
}).then(() => {
|
||||
scrollBox.onscroll = () => {
|
||||
if (scrollBox.scrollTop == oldScrollTop) {
|
||||
// Wait for scroll to change.
|
||||
return;
|
||||
}
|
||||
scrollBox.onscroll = null;
|
||||
isnot(scrollBox.scrollTop, oldScrollTop, "scroll location updated (moved to bottom again)");
|
||||
testNext();
|
||||
};
|
||||
});
|
||||
|
||||
yield undefined;
|
||||
|
||||
hud = testDriver = null;
|
||||
finishTest();
|
||||
scrollBox.onscroll = () => {
|
||||
if (scrollBox.scrollTop == oldScrollTop) {
|
||||
// Wait for scroll to change.
|
||||
return;
|
||||
}
|
||||
scrollBox.onscroll = null;
|
||||
isnot(scrollBox.scrollTop, oldScrollTop, "scroll location updated (moved to bottom again)");
|
||||
hud = testDriver = null;
|
||||
finishTest();
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
let WebConsoleUtils, TargetFactory, require;
|
||||
let {gDevTools} = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
|
||||
let {console} = Cu.import("resource://gre/modules/devtools/Console.jsm", {});
|
||||
let {Promise: promise} = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
|
||||
let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
let {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||
|
||||
(() => {
|
||||
|
|
|
@ -14,7 +14,7 @@ loader.lazyServiceGetter(this, "clipboardHelper",
|
|||
"@mozilla.org/widget/clipboardhelper;1",
|
||||
"nsIClipboardHelper");
|
||||
loader.lazyImporter(this, "Services", "resource://gre/modules/Services.jsm");
|
||||
loader.lazyGetter(this, "promise", () => require("sdk/core/promise"));
|
||||
loader.lazyImporter(this, "promise", "resource://gre/modules/Promise.jsm", "Promise");
|
||||
loader.lazyGetter(this, "EventEmitter", () => require("devtools/shared/event-emitter"));
|
||||
loader.lazyGetter(this, "AutocompletePopup",
|
||||
() => require("devtools/shared/autocomplete-popup").AutocompletePopup);
|
||||
|
|
|
@ -87,7 +87,7 @@ nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell, nsStyleContext* aContex
|
|||
mPopupAnchor(POPUPALIGNMENT_NONE),
|
||||
mPosition(POPUPPOSITION_UNKNOWN),
|
||||
mConsumeRollupEvent(nsIPopupBoxObject::ROLLUP_DEFAULT),
|
||||
mFlipBoth(false),
|
||||
mFlip(FlipType_Default),
|
||||
mIsOpenChanged(false),
|
||||
mIsContextMenu(false),
|
||||
mAdjustOffsetForContextMenu(false),
|
||||
|
@ -581,8 +581,13 @@ nsMenuPopupFrame::InitializePopup(nsIContent* aAnchorContent,
|
|||
position.Assign(aPosition);
|
||||
}
|
||||
|
||||
mFlipBoth = flip.EqualsLiteral("both");
|
||||
mSlide = flip.EqualsLiteral("slide");
|
||||
if (flip.EqualsLiteral("none")) {
|
||||
mFlip = FlipType_None;
|
||||
} else if (flip.EqualsLiteral("both")) {
|
||||
mFlip = FlipType_Both;
|
||||
} else if (flip.EqualsLiteral("slide")) {
|
||||
mFlip = FlipType_Slide;
|
||||
}
|
||||
|
||||
position.CompressWhitespace();
|
||||
int32_t spaceIdx = position.FindChar(' ');
|
||||
|
@ -685,8 +690,7 @@ nsMenuPopupFrame::InitializePopupAtScreen(nsIContent* aTriggerContent,
|
|||
mTriggerContent = aTriggerContent;
|
||||
mScreenXPos = aXPos;
|
||||
mScreenYPos = aYPos;
|
||||
mFlipBoth = false;
|
||||
mSlide = false;
|
||||
mFlip = FlipType_Default;
|
||||
mPopupAnchor = POPUPALIGNMENT_NONE;
|
||||
mPopupAlignment = POPUPALIGNMENT_NONE;
|
||||
mIsContextMenu = aIsContextMenu;
|
||||
|
@ -703,8 +707,7 @@ nsMenuPopupFrame::InitializePopupWithAnchorAlign(nsIContent* aAnchorContent,
|
|||
|
||||
mPopupState = ePopupShowing;
|
||||
mAdjustOffsetForContextMenu = false;
|
||||
mFlipBoth = false;
|
||||
mSlide = false;
|
||||
mFlip = FlipType_Default;
|
||||
|
||||
// this popup opening function is provided for backwards compatibility
|
||||
// only. It accepts either coordinates or an anchor and alignment value
|
||||
|
@ -981,7 +984,7 @@ nsMenuPopupFrame::AdjustPositionForAnchorAlign(nsRect& anchorRect,
|
|||
break;
|
||||
default:
|
||||
{
|
||||
FlipStyle anchorEdge = mFlipBoth ? FlipStyle_Inside : FlipStyle_None;
|
||||
FlipStyle anchorEdge = mFlip == FlipType_Both ? FlipStyle_Inside : FlipStyle_None;
|
||||
aHFlip = (popupAnchor == -popupAlign) ? FlipStyle_Outside : anchorEdge;
|
||||
if (((popupAnchor > 0) == (popupAlign > 0)) ||
|
||||
(popupAnchor == POPUPALIGNMENT_TOPLEFT && popupAlign == POPUPALIGNMENT_TOPLEFT))
|
||||
|
@ -1271,9 +1274,9 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove)
|
|||
vFlip = FlipStyle_Outside;
|
||||
}
|
||||
|
||||
// If a panel is being moved, don't constrain or flip it. But always do this for
|
||||
// If a panel is being moved or has flip="none", don't constrain or flip it. But always do this for
|
||||
// content shells, so that the popup doesn't extend outside the containing frame.
|
||||
if (mInContentShell || !aIsMove || mPopupType != ePopupTypePanel) {
|
||||
if (mInContentShell || (mFlip != FlipType_None && (!aIsMove || mPopupType != ePopupTypePanel))) {
|
||||
nsRect screenRect = GetConstraintRect(anchorRect, rootScreenRect);
|
||||
|
||||
// ensure that anchorRect is on screen
|
||||
|
@ -1303,7 +1306,7 @@ nsMenuPopupFrame::SetPopupPosition(nsIFrame* aAnchorFrame, bool aIsMove)
|
|||
// but we can only slide on one axis - the other axis must be "flipped or
|
||||
// resized" as normal.
|
||||
bool slideHorizontal = false, slideVertical = false;
|
||||
if (mSlide) {
|
||||
if (mFlip == FlipType_Slide) {
|
||||
int8_t position = GetAlignmentPosition();
|
||||
slideHorizontal = position >= POPUPPOSITION_BEFORESTART &&
|
||||
position <= POPUPPOSITION_AFTEREND;
|
||||
|
|
|
@ -65,6 +65,14 @@ enum FlipStyle {
|
|||
FlipStyle_Inside = 2
|
||||
};
|
||||
|
||||
// Values for the flip attribute
|
||||
enum FlipType {
|
||||
FlipType_Default = 0,
|
||||
FlipType_None = 1, // don't try to flip or translate to stay onscreen
|
||||
FlipType_Both = 2, // flip in both directions
|
||||
FlipType_Slide = 3 // allow the arrow to "slide" instead of resizing
|
||||
};
|
||||
|
||||
// values are selected so that the direction can be flipped just by
|
||||
// changing the sign
|
||||
#define POPUPALIGNMENT_NONE 0
|
||||
|
@ -459,8 +467,7 @@ protected:
|
|||
|
||||
// One of nsIPopupBoxObject::ROLLUP_DEFAULT/ROLLUP_CONSUME/ROLLUP_NO_CONSUME
|
||||
int8_t mConsumeRollupEvent;
|
||||
bool mFlipBoth; // flip in both directions
|
||||
bool mSlide; // allow the arrow to "slide" instead of resizing
|
||||
FlipType mFlip; // Whether to flip
|
||||
|
||||
bool mIsOpenChanged; // true if the open state changed since the last layout
|
||||
bool mIsContextMenu; // true for context menus
|
||||
|
|
|
@ -7,12 +7,11 @@ package org.mozilla.gecko;
|
|||
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
|
||||
|
||||
import java.lang.Thread;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class GeckoJavaSampler {
|
||||
|
@ -63,7 +62,7 @@ public class GeckoJavaSampler {
|
|||
private boolean mPauseSampler = false;
|
||||
private boolean mStopSampler = false;
|
||||
|
||||
private Map<Integer,Sample[]> mSamples = new HashMap<Integer,Sample[]>();
|
||||
private SparseArray<Sample[]> mSamples = new SparseArray<Sample[]>();
|
||||
private int mSamplePos;
|
||||
|
||||
public SamplingThread(final int aInterval, final int aSampleCount) {
|
||||
|
|
|
@ -12,10 +12,9 @@ import org.json.JSONException;
|
|||
import org.json.JSONObject;
|
||||
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Helper class to get/set gecko prefs.
|
||||
|
@ -24,7 +23,7 @@ public final class PrefsHelper {
|
|||
private static final String LOGTAG = "GeckoPrefsHelper";
|
||||
|
||||
private static boolean sRegistered = false;
|
||||
private static final Map<Integer, PrefHandler> sCallbacks = new HashMap<Integer, PrefHandler>();
|
||||
private static final SparseArray<PrefHandler> sCallbacks = new SparseArray<PrefHandler>();
|
||||
private static int sUniqueRequestId = 1;
|
||||
|
||||
public static int getPref(String prefName, PrefHandler callback) {
|
||||
|
@ -73,7 +72,7 @@ public final class PrefsHelper {
|
|||
int requestId = message.getInt("requestId");
|
||||
callback = sCallbacks.get(requestId);
|
||||
if (callback != null && !callback.isObserver()) {
|
||||
sCallbacks.remove(requestId);
|
||||
sCallbacks.delete(requestId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
callback = null;
|
||||
|
@ -144,7 +143,9 @@ public final class PrefsHelper {
|
|||
}
|
||||
|
||||
synchronized (PrefsHelper.class) {
|
||||
PrefHandler callback = sCallbacks.remove(requestId);
|
||||
PrefHandler callback = sCallbacks.get(requestId);
|
||||
sCallbacks.delete(requestId);
|
||||
|
||||
if (callback == null) {
|
||||
Log.e(LOGTAG, "Unknown request ID " + requestId);
|
||||
return;
|
||||
|
|
|
@ -23,15 +23,14 @@ import android.graphics.Bitmap;
|
|||
import android.graphics.BitmapFactory;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Favicons {
|
||||
|
@ -62,7 +61,7 @@ public class Favicons {
|
|||
// The density-adjusted maximum Favicon dimensions.
|
||||
public static int sLargestFaviconSize;
|
||||
|
||||
private static final Map<Integer, LoadFaviconTask> sLoadTasks = Collections.synchronizedMap(new HashMap<Integer, LoadFaviconTask>());
|
||||
private static final SparseArray<LoadFaviconTask> sLoadTasks = new SparseArray<LoadFaviconTask>();
|
||||
|
||||
// Cache to hold mappings between page URLs and Favicon URLs. Used to avoid going to the DB when
|
||||
// doing so is not necessary.
|
||||
|
@ -217,7 +216,9 @@ public class Favicons {
|
|||
// No joy using in-memory resources. Go to background thread and ask the database.
|
||||
LoadFaviconTask task = new LoadFaviconTask(ThreadUtils.getBackgroundHandler(), pageURL, targetURL, 0, callback, targetSize, true);
|
||||
int taskId = task.getId();
|
||||
sLoadTasks.put(taskId, task);
|
||||
synchronized(sLoadTasks) {
|
||||
sLoadTasks.put(taskId, task);
|
||||
}
|
||||
task.execute();
|
||||
return taskId;
|
||||
}
|
||||
|
@ -282,7 +283,9 @@ public class Favicons {
|
|||
LoadFaviconTask task = new LoadFaviconTask(ThreadUtils.getBackgroundHandler(), pageUrl, faviconUrl, flags, listener, targetSize, false);
|
||||
|
||||
int taskId = task.getId();
|
||||
sLoadTasks.put(taskId, task);
|
||||
synchronized(sLoadTasks) {
|
||||
sLoadTasks.put(taskId, task);
|
||||
}
|
||||
|
||||
task.execute();
|
||||
|
||||
|
@ -325,7 +328,7 @@ public class Favicons {
|
|||
|
||||
boolean cancelled;
|
||||
synchronized (sLoadTasks) {
|
||||
if (!sLoadTasks.containsKey(taskId))
|
||||
if (sLoadTasks.indexOfKey(taskId) < 0)
|
||||
return false;
|
||||
|
||||
Log.d(LOGTAG, "Cancelling favicon load (" + taskId + ")");
|
||||
|
@ -341,11 +344,9 @@ public class Favicons {
|
|||
|
||||
// Cancel any pending tasks
|
||||
synchronized (sLoadTasks) {
|
||||
Set<Integer> taskIds = sLoadTasks.keySet();
|
||||
Iterator<Integer> iter = taskIds.iterator();
|
||||
while (iter.hasNext()) {
|
||||
int taskId = iter.next();
|
||||
cancelFaviconLoad(taskId);
|
||||
final int count = sLoadTasks.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
cancelFaviconLoad(sLoadTasks.keyAt(i));
|
||||
}
|
||||
sLoadTasks.clear();
|
||||
}
|
||||
|
@ -449,7 +450,9 @@ public class Favicons {
|
|||
}
|
||||
|
||||
public static void removeLoadTask(int taskId) {
|
||||
sLoadTasks.remove(taskId);
|
||||
synchronized(sLoadTasks) {
|
||||
sLoadTasks.delete(taskId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,8 +8,9 @@ import android.graphics.Bitmap;
|
|||
import org.mozilla.gecko.favicons.Favicons;
|
||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
|
@ -152,7 +153,7 @@ public class ICODecoder implements Iterable<Bitmap> {
|
|||
int minimumMaximum = Integer.MAX_VALUE;
|
||||
|
||||
// Used to track the best entry for each size. The entries we want to keep.
|
||||
HashMap<Integer, IconDirectoryEntry> preferenceMap = new HashMap<Integer, IconDirectoryEntry>();
|
||||
SparseArray<IconDirectoryEntry> preferenceArray = new SparseArray<IconDirectoryEntry>();
|
||||
|
||||
for (int i = 0; i < numEncodedImages; i++, bufferIndex += ICO_ICONDIRENTRY_LENGTH_BYTES) {
|
||||
// Decode the Icon Directory Entry at this offset.
|
||||
|
@ -172,42 +173,39 @@ public class ICODecoder implements Iterable<Bitmap> {
|
|||
}
|
||||
|
||||
// Remove the previous minimum-maximum.
|
||||
if (preferenceMap.containsKey(minimumMaximum)) {
|
||||
preferenceMap.remove(minimumMaximum);
|
||||
}
|
||||
preferenceArray.delete(minimumMaximum);
|
||||
|
||||
minimumMaximum = newEntry.mWidth;
|
||||
}
|
||||
|
||||
IconDirectoryEntry oldEntry = preferenceMap.get(newEntry.mWidth);
|
||||
IconDirectoryEntry oldEntry = preferenceArray.get(newEntry.mWidth);
|
||||
if (oldEntry == null) {
|
||||
preferenceMap.put(newEntry.mWidth, newEntry);
|
||||
preferenceArray.put(newEntry.mWidth, newEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oldEntry.compareTo(newEntry) < 0) {
|
||||
preferenceMap.put(newEntry.mWidth, newEntry);
|
||||
preferenceArray.put(newEntry.mWidth, newEntry);
|
||||
}
|
||||
}
|
||||
|
||||
Collection<IconDirectoryEntry> entriesRetained = preferenceMap.values();
|
||||
final int count = preferenceArray.size();
|
||||
|
||||
// Abort if no entries are desired (Perhaps all are corrupt?)
|
||||
if (entriesRetained.isEmpty()) {
|
||||
if (count == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allocate space for the icon directory entries in the decoded directory.
|
||||
mIconDirectory = new IconDirectoryEntry[entriesRetained.size()];
|
||||
mIconDirectory = new IconDirectoryEntry[count];
|
||||
|
||||
// The size of the data in the buffer that we find useful.
|
||||
int retainedSpace = ICO_HEADER_LENGTH_BYTES;
|
||||
|
||||
int dirInd = 0;
|
||||
for (IconDirectoryEntry e : entriesRetained) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
IconDirectoryEntry e = preferenceArray.valueAt(i);
|
||||
retainedSpace += ICO_ICONDIRENTRY_LENGTH_BYTES + e.mPayloadSize;
|
||||
mIconDirectory[dirInd] = e;
|
||||
dirInd++;
|
||||
mIconDirectory[i] = e;
|
||||
}
|
||||
|
||||
mIsValid = true;
|
||||
|
|
|
@ -19,11 +19,10 @@ import android.content.SharedPreferences;
|
|||
import android.preference.PreferenceManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class PanelManager implements GeckoEventListener {
|
||||
|
@ -50,7 +49,7 @@ public class PanelManager implements GeckoEventListener {
|
|||
private static AtomicInteger sRequestId = new AtomicInteger(0);
|
||||
|
||||
// Stores set of pending request callbacks.
|
||||
private static final Map<Integer, RequestCallback> sCallbacks = new HashMap<Integer, RequestCallback>();
|
||||
private static final SparseArray<RequestCallback> sCallbacks = new SparseArray<RequestCallback>();
|
||||
|
||||
/**
|
||||
* Asynchronously fetches list of available panels from Gecko.
|
||||
|
@ -62,7 +61,7 @@ public class PanelManager implements GeckoEventListener {
|
|||
|
||||
synchronized(sCallbacks) {
|
||||
// If there are no pending callbacks, register the event listener.
|
||||
if (sCallbacks.isEmpty()) {
|
||||
if (sCallbacks.size() == 0) {
|
||||
GeckoAppShell.getEventDispatcher().registerEventListener("HomePanels:Data", this);
|
||||
}
|
||||
sCallbacks.put(requestId, callback);
|
||||
|
@ -90,10 +89,11 @@ public class PanelManager implements GeckoEventListener {
|
|||
final int requestId = message.getInt("requestId");
|
||||
|
||||
synchronized(sCallbacks) {
|
||||
callback = sCallbacks.remove(requestId);
|
||||
callback = sCallbacks.get(requestId);
|
||||
sCallbacks.delete(requestId);
|
||||
|
||||
// Unregister the event listener if there are no more pending callbacks.
|
||||
if (sCallbacks.isEmpty()) {
|
||||
if (sCallbacks.size() == 0) {
|
||||
GeckoAppShell.getEventDispatcher().unregisterEventListener("HomePanels:Data", this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -205,6 +205,13 @@ public final class GeckoLoader {
|
|||
putenv("MOZ_LINKER_CACHE=" + linkerCache);
|
||||
}
|
||||
|
||||
// Disable on-demand decompression of the linker on devices where it
|
||||
// is known to cause crashes.
|
||||
if ("HTC".equals(android.os.Build.MANUFACTURER) &&
|
||||
"HTC Vision".equals(android.os.Build.MODEL)) {
|
||||
putenv("MOZ_LINKER_ONDEMAND=0");
|
||||
}
|
||||
|
||||
#ifdef MOZ_LINKER_EXTRACT
|
||||
putenv("MOZ_LINKER_EXTRACT=1");
|
||||
// Ensure that the cache dir is world-writable
|
||||
|
|
|
@ -32,25 +32,25 @@ public class AboutHomeComponent extends BaseComponent {
|
|||
READING_LIST
|
||||
}
|
||||
|
||||
// TODO: Having a specific ordering of pages is prone to fail and thus temporary.
|
||||
// TODO: Having a specific ordering of panels is prone to fail and thus temporary.
|
||||
// Hopefully the work in bug 940565 will alleviate the need for these enums.
|
||||
// Explicit ordering of HomePager pages on a phone.
|
||||
private enum PhonePage {
|
||||
// Explicit ordering of HomePager panels on a phone.
|
||||
private enum PhonePanel {
|
||||
HISTORY,
|
||||
TOP_SITES,
|
||||
BOOKMARKS,
|
||||
READING_LIST
|
||||
}
|
||||
|
||||
// Explicit ordering of HomePager pages on a tablet.
|
||||
private enum TabletPage {
|
||||
// Explicit ordering of HomePager panels on a tablet.
|
||||
private enum TabletPanel {
|
||||
TOP_SITES,
|
||||
BOOKMARKS,
|
||||
READING_LIST,
|
||||
HISTORY
|
||||
}
|
||||
|
||||
// The percentage of the page to swipe between 0 and 1. This value was set through
|
||||
// The percentage of the panel to swipe between 0 and 1. This value was set through
|
||||
// testing: 0.55f was tested on try and fails on armv6 devices.
|
||||
private static final float SWIPE_PERCENTAGE = 0.70f;
|
||||
|
||||
|
@ -62,12 +62,12 @@ public class AboutHomeComponent extends BaseComponent {
|
|||
return (ViewPager) mSolo.getView(R.id.home_pager);
|
||||
}
|
||||
|
||||
public AboutHomeComponent assertCurrentPage(final PanelType expectedPage) {
|
||||
public AboutHomeComponent assertCurrentPanel(final PanelType expectedPanel) {
|
||||
assertVisible();
|
||||
|
||||
final int expectedPageIndex = getPageIndexForDevice(expectedPage.ordinal());
|
||||
assertEquals("The current HomePager page is " + expectedPage,
|
||||
expectedPageIndex, getHomePagerView().getCurrentItem());
|
||||
final int expectedPanelIndex = getPanelIndexForDevice(expectedPanel.ordinal());
|
||||
assertEquals("The current HomePager panel is " + expectedPanel,
|
||||
expectedPanelIndex, getHomePagerView().getCurrentItem());
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -83,46 +83,46 @@ public class AboutHomeComponent extends BaseComponent {
|
|||
return this;
|
||||
}
|
||||
|
||||
public AboutHomeComponent swipeToPageOnRight() {
|
||||
mTestContext.dumpLog(LOGTAG, "Swiping to the page on the right.");
|
||||
swipeToPage(Solo.RIGHT);
|
||||
public AboutHomeComponent swipeToPanelOnRight() {
|
||||
mTestContext.dumpLog(LOGTAG, "Swiping to the panel on the right.");
|
||||
swipeToPanel(Solo.RIGHT);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AboutHomeComponent swipeToPageOnLeft() {
|
||||
mTestContext.dumpLog(LOGTAG, "Swiping to the page on the left.");
|
||||
swipeToPage(Solo.LEFT);
|
||||
public AboutHomeComponent swipeToPanelOnLeft() {
|
||||
mTestContext.dumpLog(LOGTAG, "Swiping to the panel on the left.");
|
||||
swipeToPanel(Solo.LEFT);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void swipeToPage(final int pageDirection) {
|
||||
assertTrue("Swiping in a vaild direction",
|
||||
pageDirection == Solo.LEFT || pageDirection == Solo.RIGHT);
|
||||
private void swipeToPanel(final int panelDirection) {
|
||||
assertTrue("Swiping in a valid direction",
|
||||
panelDirection == Solo.LEFT || panelDirection == Solo.RIGHT);
|
||||
assertVisible();
|
||||
|
||||
final int pageIndex = getHomePagerView().getCurrentItem();
|
||||
final int panelIndex = getHomePagerView().getCurrentItem();
|
||||
|
||||
mSolo.scrollViewToSide(getHomePagerView(), pageDirection, SWIPE_PERCENTAGE);
|
||||
mSolo.scrollViewToSide(getHomePagerView(), panelDirection, SWIPE_PERCENTAGE);
|
||||
|
||||
// The page on the left is a lower index and vice versa.
|
||||
final int unboundedPageIndex = pageIndex + (pageDirection == Solo.LEFT ? -1 : 1);
|
||||
final int pageCount = DeviceHelper.isTablet() ?
|
||||
TabletPage.values().length : PhonePage.values().length;
|
||||
final int maxPageIndex = pageCount - 1;
|
||||
final int expectedPageIndex = Math.min(Math.max(0, unboundedPageIndex), maxPageIndex);
|
||||
// The panel on the left is a lower index and vice versa.
|
||||
final int unboundedPanelIndex = panelIndex + (panelDirection == Solo.LEFT ? -1 : 1);
|
||||
final int panelCount = DeviceHelper.isTablet() ?
|
||||
TabletPanel.values().length : PhonePanel.values().length;
|
||||
final int maxPanelIndex = panelCount - 1;
|
||||
final int expectedPanelIndex = Math.min(Math.max(0, unboundedPanelIndex), maxPanelIndex);
|
||||
|
||||
waitForPageIndex(expectedPageIndex);
|
||||
waitForPanelIndex(expectedPanelIndex);
|
||||
}
|
||||
|
||||
private void waitForPageIndex(final int expectedIndex) {
|
||||
final String pageName;
|
||||
private void waitForPanelIndex(final int expectedIndex) {
|
||||
final String panelName;
|
||||
if (DeviceHelper.isTablet()) {
|
||||
pageName = TabletPage.values()[expectedIndex].name();
|
||||
panelName = TabletPanel.values()[expectedIndex].name();
|
||||
} else {
|
||||
pageName = PhonePage.values()[expectedIndex].name();
|
||||
panelName = PhonePanel.values()[expectedIndex].name();
|
||||
}
|
||||
|
||||
WaitHelper.waitFor("HomePager " + pageName + " page", new Condition() {
|
||||
WaitHelper.waitFor("HomePager " + panelName + " panel", new Condition() {
|
||||
@Override
|
||||
public boolean isSatisfied() {
|
||||
return (getHomePagerView().getCurrentItem() == expectedIndex);
|
||||
|
@ -131,13 +131,13 @@ public class AboutHomeComponent extends BaseComponent {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the page index in the device specific Page enum for the given index in the
|
||||
* Gets the panel index in the device specific Panel enum for the given index in the
|
||||
* PanelType enum.
|
||||
*/
|
||||
private int getPageIndexForDevice(final int pageIndex) {
|
||||
final String pageName = PanelType.values()[pageIndex].name();
|
||||
final Class devicePageEnum =
|
||||
DeviceHelper.isTablet() ? TabletPage.class : PhonePage.class;
|
||||
return Enum.valueOf(devicePageEnum, pageName).ordinal();
|
||||
private int getPanelIndexForDevice(final int panelIndex) {
|
||||
final String panelName = PanelType.values()[panelIndex].name();
|
||||
final Class devicePanelEnum =
|
||||
DeviceHelper.isTablet() ? TabletPanel.class : PhonePanel.class;
|
||||
return Enum.valueOf(devicePanelEnum, panelName).ordinal();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,23 +6,23 @@ import org.mozilla.gecko.tests.components.AboutHomeComponent.PanelType;
|
|||
import org.mozilla.gecko.tests.helpers.*;
|
||||
|
||||
/**
|
||||
* Tests functionality related to navigating between the various about:home pages.
|
||||
* Tests functionality related to navigating between the various about:home panels.
|
||||
*/
|
||||
public class testAboutHomePageNavigation extends UITest {
|
||||
// TODO: Define this test dynamically by creating dynamic representations of the Page
|
||||
// enum for both phone and tablet, then swiping through the pages. This will also
|
||||
// benefit having a HomePager with custom pages.
|
||||
// enum for both phone and tablet, then swiping through the panels. This will also
|
||||
// benefit having a HomePager with custom panels.
|
||||
public void testAboutHomePageNavigation() {
|
||||
GeckoHelper.blockForReady();
|
||||
|
||||
mAboutHome.assertVisible()
|
||||
.assertCurrentPage(PanelType.TOP_SITES);
|
||||
.assertCurrentPanel(PanelType.TOP_SITES);
|
||||
|
||||
mAboutHome.swipeToPageOnRight();
|
||||
mAboutHome.assertCurrentPage(PanelType.BOOKMARKS);
|
||||
mAboutHome.swipeToPanelOnRight();
|
||||
mAboutHome.assertCurrentPanel(PanelType.BOOKMARKS);
|
||||
|
||||
mAboutHome.swipeToPageOnRight();
|
||||
mAboutHome.assertCurrentPage(PanelType.READING_LIST);
|
||||
mAboutHome.swipeToPanelOnRight();
|
||||
mAboutHome.assertCurrentPanel(PanelType.READING_LIST);
|
||||
|
||||
// Ideally these helpers would just be their own tests. However, by keeping this within
|
||||
// one method, we're saving test setUp and tearDown resources.
|
||||
|
@ -34,47 +34,47 @@ public class testAboutHomePageNavigation extends UITest {
|
|||
}
|
||||
|
||||
private void helperTestTablet() {
|
||||
mAboutHome.swipeToPageOnRight();
|
||||
mAboutHome.assertCurrentPage(PanelType.HISTORY);
|
||||
mAboutHome.swipeToPanelOnRight();
|
||||
mAboutHome.assertCurrentPanel(PanelType.HISTORY);
|
||||
|
||||
// Edge case.
|
||||
mAboutHome.swipeToPageOnRight();
|
||||
mAboutHome.assertCurrentPage(PanelType.HISTORY);
|
||||
mAboutHome.swipeToPanelOnRight();
|
||||
mAboutHome.assertCurrentPanel(PanelType.HISTORY);
|
||||
|
||||
mAboutHome.swipeToPageOnLeft();
|
||||
mAboutHome.assertCurrentPage(PanelType.READING_LIST);
|
||||
mAboutHome.swipeToPanelOnLeft();
|
||||
mAboutHome.assertCurrentPanel(PanelType.READING_LIST);
|
||||
|
||||
mAboutHome.swipeToPageOnLeft();
|
||||
mAboutHome.assertCurrentPage(PanelType.BOOKMARKS);
|
||||
mAboutHome.swipeToPanelOnLeft();
|
||||
mAboutHome.assertCurrentPanel(PanelType.BOOKMARKS);
|
||||
|
||||
mAboutHome.swipeToPageOnLeft();
|
||||
mAboutHome.assertCurrentPage(PanelType.TOP_SITES);
|
||||
mAboutHome.swipeToPanelOnLeft();
|
||||
mAboutHome.assertCurrentPanel(PanelType.TOP_SITES);
|
||||
|
||||
// Edge case.
|
||||
mAboutHome.swipeToPageOnLeft();
|
||||
mAboutHome.assertCurrentPage(PanelType.TOP_SITES);
|
||||
mAboutHome.swipeToPanelOnLeft();
|
||||
mAboutHome.assertCurrentPanel(PanelType.TOP_SITES);
|
||||
}
|
||||
|
||||
private void helperTestPhone() {
|
||||
// Edge case.
|
||||
mAboutHome.swipeToPageOnRight();
|
||||
mAboutHome.assertCurrentPage(PanelType.READING_LIST);
|
||||
mAboutHome.swipeToPanelOnRight();
|
||||
mAboutHome.assertCurrentPanel(PanelType.READING_LIST);
|
||||
|
||||
mAboutHome.swipeToPageOnLeft();
|
||||
mAboutHome.assertCurrentPage(PanelType.BOOKMARKS);
|
||||
mAboutHome.swipeToPanelOnLeft();
|
||||
mAboutHome.assertCurrentPanel(PanelType.BOOKMARKS);
|
||||
|
||||
mAboutHome.swipeToPageOnLeft();
|
||||
mAboutHome.assertCurrentPage(PanelType.TOP_SITES);
|
||||
mAboutHome.swipeToPanelOnLeft();
|
||||
mAboutHome.assertCurrentPanel(PanelType.TOP_SITES);
|
||||
|
||||
mAboutHome.swipeToPageOnLeft();
|
||||
mAboutHome.assertCurrentPage(PanelType.HISTORY);
|
||||
mAboutHome.swipeToPanelOnLeft();
|
||||
mAboutHome.assertCurrentPanel(PanelType.HISTORY);
|
||||
|
||||
// Edge case.
|
||||
mAboutHome.swipeToPageOnLeft();
|
||||
mAboutHome.assertCurrentPage(PanelType.HISTORY);
|
||||
mAboutHome.swipeToPanelOnLeft();
|
||||
mAboutHome.assertCurrentPanel(PanelType.HISTORY);
|
||||
|
||||
mAboutHome.swipeToPageOnRight();
|
||||
mAboutHome.assertCurrentPage(PanelType.TOP_SITES);
|
||||
mAboutHome.swipeToPanelOnRight();
|
||||
mAboutHome.assertCurrentPanel(PanelType.TOP_SITES);
|
||||
}
|
||||
|
||||
// TODO: bug 943706 - reimplement this old test code.
|
||||
|
|
|
@ -15,7 +15,7 @@ public class testAboutHomeVisibility extends UITest {
|
|||
// Check initial state on about:home.
|
||||
mToolbar.assertTitle(StringHelper.ABOUT_HOME_TITLE);
|
||||
mAboutHome.assertVisible()
|
||||
.assertCurrentPage(PanelType.TOP_SITES);
|
||||
.assertCurrentPanel(PanelType.TOP_SITES);
|
||||
|
||||
// Go to blank 01.
|
||||
NavigationHelper.enterAndLoadUrl(StringHelper.ROBOCOP_BLANK_PAGE_01_URL);
|
||||
|
@ -30,7 +30,7 @@ public class testAboutHomeVisibility extends UITest {
|
|||
// Enter editing mode, where the about:home UI should be visible.
|
||||
mToolbar.enterEditingMode();
|
||||
mAboutHome.assertVisible()
|
||||
.assertCurrentPage(PanelType.TOP_SITES);
|
||||
.assertCurrentPanel(PanelType.TOP_SITES);
|
||||
|
||||
// Dismiss editing mode, where the about:home UI should be gone.
|
||||
mToolbar.dismissEditingMode();
|
||||
|
@ -40,7 +40,7 @@ public class testAboutHomeVisibility extends UITest {
|
|||
NavigationHelper.enterAndLoadUrl(StringHelper.ABOUT_HOME_URL);
|
||||
mToolbar.assertTitle(StringHelper.ABOUT_HOME_TITLE);
|
||||
mAboutHome.assertVisible()
|
||||
.assertCurrentPage(PanelType.TOP_SITES);
|
||||
.assertCurrentPanel(PanelType.TOP_SITES);
|
||||
|
||||
// TODO: Type in a url and assert the go button is visible.
|
||||
}
|
||||
|
|
|
@ -4,11 +4,10 @@
|
|||
|
||||
package org.mozilla.gecko.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import android.util.SparseArray;
|
||||
|
||||
public final class ActivityResultHandlerMap {
|
||||
private Map<Integer, ActivityResultHandler> mMap = new HashMap<Integer, ActivityResultHandler>();
|
||||
private SparseArray<ActivityResultHandler> mMap = new SparseArray<ActivityResultHandler>();
|
||||
private int mCounter = 0;
|
||||
|
||||
public synchronized int put(ActivityResultHandler handler) {
|
||||
|
@ -17,6 +16,9 @@ public final class ActivityResultHandlerMap {
|
|||
}
|
||||
|
||||
public synchronized ActivityResultHandler getAndRemove(int i) {
|
||||
return mMap.remove(i);
|
||||
ActivityResultHandler handler = mMap.get(i);
|
||||
mMap.delete(i);
|
||||
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -254,7 +254,54 @@ var tests = [
|
|||
is(panel.getOuterScreenRect().top, 245, testname + "top");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
// The panel should be allowed to appear and remain offscreen
|
||||
testname: "normal panel with flip='none' off-screen",
|
||||
attrs: { "flip": "none" },
|
||||
test: function(panel) {
|
||||
panel.openPopup(document.documentElement, "", -100 - mozInnerScreenX, -100 - mozInnerScreenY, false, false, null);
|
||||
},
|
||||
result: function(testname, panel) {
|
||||
var panelrect = panel.getBoundingClientRect();
|
||||
is(panelrect.left, -100 - mozInnerScreenX, testname + "left");
|
||||
is(panelrect.top, -100 - mozInnerScreenY, testname + "top");
|
||||
is(panelrect.width, 120, testname + "width");
|
||||
is(panelrect.height, 40, testname + "height");
|
||||
|
||||
var screenRect = panel.getOuterScreenRect();
|
||||
is(screenRect.left, -100, testname + " screen left");
|
||||
is(screenRect.top, -100, testname + " screen top");
|
||||
is(screenRect.width, 120, testname + " screen width");
|
||||
is(screenRect.height, 40, testname + " screen height");
|
||||
}
|
||||
},
|
||||
{
|
||||
// The panel should be allowed to remain offscreen after moving and it should follow the anchor
|
||||
testname: "normal panel with flip='none' moved off-screen",
|
||||
attrs: { "flip": "none" },
|
||||
test: function(panel) {
|
||||
panel.openPopup(document.documentElement, "", -100 - mozInnerScreenX, -100 - mozInnerScreenY, false, false, null);
|
||||
window.moveBy(-50, -50);
|
||||
},
|
||||
result: function(testname, panel) {
|
||||
if (navigator.platform.indexOf("Linux") >= 0) {
|
||||
// The window position doesn't get updated immediately on Linux.
|
||||
return;
|
||||
}
|
||||
var panelrect = panel.getBoundingClientRect();
|
||||
is(panelrect.left, -150 - mozInnerScreenX, testname + "left");
|
||||
is(panelrect.top, -150 - mozInnerScreenY, testname + "top");
|
||||
is(panelrect.width, 120, testname + "width");
|
||||
is(panelrect.height, 40, testname + "height");
|
||||
|
||||
var screenRect = panel.getOuterScreenRect();
|
||||
is(screenRect.left, -150, testname + " screen left");
|
||||
is(screenRect.top, -150, testname + " screen top");
|
||||
is(screenRect.width, 120, testname + " screen width");
|
||||
is(screenRect.height, 40, testname + " screen height");
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
window.opener.wrappedJSObject.SimpleTest.waitForFocus(test_panels, window);
|
||||
|
|
|
@ -24,6 +24,27 @@ let progressListener = {
|
|||
Ci.nsISupportsWeakReference]),
|
||||
onLocationChange: function onLocationChange(progress, request, location,
|
||||
flags) {
|
||||
|
||||
// Close tooltip (code adapted from /browser/base/content/browser.js)
|
||||
let pageTooltip = document.getElementById("contentAreaTooltip");
|
||||
let tooltipNode = pageTooltip.triggerNode;
|
||||
if (tooltipNode) {
|
||||
// Optimise for the common case
|
||||
if (progress.isTopLevel) {
|
||||
pageTooltip.hidePopup();
|
||||
}
|
||||
else {
|
||||
for (let tooltipWindow = tooltipNode.ownerDocument.defaultView;
|
||||
tooltipWindow != tooltipWindow.parent;
|
||||
tooltipWindow = tooltipWindow.parent) {
|
||||
if (tooltipWindow == progress.DOMWindow) {
|
||||
pageTooltip.hidePopup();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the title of the window to the name of the webapp, adding the origin
|
||||
// of the page being loaded if it's from a different origin than the app
|
||||
// (per security bug 741955, which specifies that other-origin pages loaded
|
||||
|
|
|
@ -155,13 +155,14 @@
|
|||
</menu>
|
||||
</menubar>
|
||||
|
||||
<browser type="content-primary" id="content" flex="1" context="contentAreaContextMenu" />
|
||||
<browser type="content-primary" id="content" flex="1" context="contentAreaContextMenu" tooltip="contentAreaTooltip" />
|
||||
|
||||
<popupset>
|
||||
<menupopup id="contentAreaContextMenu" pagemenu="start"
|
||||
onpopupshowing="return showContextMenu(event, this)"
|
||||
onpopuphiding="hideContextMenu(event, this)">
|
||||
</menupopup>
|
||||
<tooltip id="contentAreaTooltip" page="true" />
|
||||
</popupset>
|
||||
|
||||
</window>
|
||||
|
|
Загрузка…
Ссылка в новой задаче