Merge mozilla-central and fx-team

This commit is contained in:
Ed Morley 2013-08-28 16:22:11 +01:00
commit c9d090652c
13 changed files with 164 additions and 111 deletions

View File

@ -236,7 +236,12 @@ function make(document) {
let viewFrame = createFrame(panel, frameOptions);
setupPanelFrame(viewFrame);
function onDisplayChange({type}) {
function onDisplayChange({type, target}) {
// Events from child element like <select /> may propagate (dropdowns are
// popups too), in which case frame loader shouldn't be swapped.
// See Bug 886329
if (target !== this) return;
try { swapFrameLoaders(backgroundFrame, viewFrame); }
catch(error) { console.exception(error); }
events.emit(type, { subject: panel });

View File

@ -5,7 +5,8 @@
const { defer } = require('../core/promise');
const events = require('../system/events');
const { open: openWindow, onFocus, getToplevelWindow } = require('./utils');
const { open: openWindow, onFocus, getToplevelWindow,
isInteractive } = require('./utils');
function open(uri, options) {
return promise(openWindow.apply(null, arguments), 'load');
@ -36,6 +37,18 @@ function focus(window) {
}
exports.focus = focus;
function ready(window) {
let { promise: result, resolve } = defer();
if (isInteractive(window))
resolve(window);
else
resolve(promise(window, 'DOMContentLoaded'));
return result;
}
exports.ready = ready;
function promise(target, evt, capture) {
let deferred = defer();
capture = !!capture;
@ -47,4 +60,4 @@ function promise(target, evt, capture) {
return deferred.promise;
}
exports.promise = promise;
exports.promise = promise;

View File

@ -1,27 +1,27 @@
/* 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/. */
"use strict";
var errors = require("sdk/deprecated/errors");
const errors = require("sdk/deprecated/errors");
exports.testCatchAndLog = function(test) {
exports.testCatchAndLog = function(assert) {
var caught = [];
function dummyLog(e) { caught.push(e); }
var wrapped = errors.catchAndLog(function(x) {
throw Error("blah" + x + this);
},
"boop",
dummyLog);
test.assertEqual(wrapped.call("hi", 1), "boop",
"exceptions should be trapped, def. resp. returned");
test.assertEqual(caught.length, 1,
"logging function should be called");
test.assertEqual(caught[0].message, "blah1hi",
"args and this should be passed to wrapped func");
throw Error("blah" + x + this);
}, "boop", dummyLog);
assert.equal(wrapped.call("hi", 1), "boop",
"exceptions should be trapped, def. resp. returned");
assert.equal(caught.length, 1,
"logging function should be called");
assert.equal(caught[0].message, "blah1hi",
"args and this should be passed to wrapped func");
};
exports.testCatchAndLogProps = function(test) {
exports.testCatchAndLogProps = function(assert) {
var caught = [];
function dummyLog(e) { caught.push(e); }
@ -33,38 +33,40 @@ exports.testCatchAndLogProps = function(test) {
errors.catchAndLogProps(thing, "foo", "ugh", dummyLog);
test.assertEqual(thing.foo(1), "ugh",
assert.equal(thing.foo(1), "ugh",
"props should be wrapped");
test.assertEqual(caught.length, 1,
assert.equal(caught.length, 1,
"logging function should be called");
test.assertEqual(caught[0].message, "nowai1",
assert.equal(caught[0].message, "nowai1",
"args should be passed to wrapped func");
test.assertRaises(function() { thing.bar(); },
"blah",
"non-wrapped props should be wrapped");
assert.throws(function() { thing.bar(); },
/blah/,
"non-wrapped props should be wrapped");
errors.catchAndLogProps(thing, ["bar", "baz"], "err", dummyLog);
test.assert((thing.bar() == thing.baz()) &&
assert.ok((thing.bar() == thing.baz()) &&
(thing.bar() == "err"),
"multiple props should be wrapped if array passed in");
};
exports.testCatchAndReturn = function(test) {
exports.testCatchAndReturn = function(assert) {
var wrapped = errors.catchAndReturn(function(x) {
if (x == 1)
return "one";
if (x == 2)
throw new Error("two");
return this + x;
});
if (x == 1)
return "one";
if (x == 2)
throw new Error("two");
return this + x;
});
test.assertEqual(wrapped(1).returnValue, "one",
"arg should be passed; return value should be returned");
test.assert(wrapped(2).exception, "exception should be returned");
test.assertEqual(wrapped(2).exception.message, "two", "message is correct");
test.assert(wrapped(2).exception.fileName.indexOf("test-errors.js") != -1,
"filename is present");
test.assert(wrapped(2).exception.stack, "stack is available");
test.assertEqual(wrapped.call("hi", 3).returnValue, "hi3",
"`this` should be set correctly");
assert.equal(wrapped(1).returnValue, "one",
"arg should be passed; return value should be returned");
assert.ok(wrapped(2).exception, "exception should be returned");
assert.equal(wrapped(2).exception.message, "two", "message is correct");
assert.ok(wrapped(2).exception.fileName.indexOf("test-errors.js") != -1,
"filename is present");
assert.ok(wrapped(2).exception.stack, "stack is available");
assert.equal(wrapped.call("hi", 3).returnValue, "hi3",
"`this` should be set correctly");
};
require("sdk/test").run(exports);

View File

@ -14,7 +14,7 @@ const { Loader } = require('sdk/test/loader');
const { LoaderWithHookedConsole } = require("sdk/test/loader");
const timer = require("sdk/timers");
const self = require('sdk/self');
const { open, close, focus } = require('sdk/window/helpers');
const { open, close, focus, ready } = require('sdk/window/helpers');
const { isPrivate } = require('sdk/private-browsing');
const { isWindowPBSupported, isGlobalPBSupported } = require('sdk/private-browsing/utils');
const { defer, all } = require('sdk/core/promise');
@ -896,6 +896,43 @@ exports['test passing DOM node as first argument'] = function (assert, done) {
panel.show(widgetNode);
};
// This test is checking that `onpupshowing` events emitted by panel's children
// are not considered.
// See Bug 886329
exports['test nested popups'] = function (assert, done) {
let loader = Loader(module);
let { Panel } = loader.require('sdk/panel');
let { getActiveView } = loader.require('sdk/view/core');
let url = '<select><option>1<option>2<option>3</select>';
let getContentWindow = panel => {
return getActiveView(panel).querySelector('iframe').contentWindow;
}
let panel = Panel({
contentURL: 'data:text/html;charset=utf-8,' + encodeURIComponent(url),
onShow: () => {
ready(getContentWindow(panel)).then(({ window, document }) => {
let select = document.querySelector('select');
let event = document.createEvent('UIEvent');
event.initUIEvent('popupshowing', true, true, window, null);
select.dispatchEvent(event);
assert.equal(
select,
getContentWindow(panel).document.querySelector('select'),
'select is still loaded in panel'
);
done();
});
}
});
panel.show();
};
if (isWindowPBSupported) {
exports.testGetWindow = function(assert, done) {
let activeWindow = getMostRecentBrowserWindow();

View File

@ -743,7 +743,7 @@ var AlertsHelper = {
this._listeners[uid] = listener;
let app = DOMApplicationRegistry.getAppByManifestURL(listener.manifestURL);
DOMApplicationRegistry.getManifestFor(app.origin, function(manifest) {
DOMApplicationRegistry.getManifestFor(app.manifestURL, function(manifest) {
let helper = new ManifestHelper(manifest, app.origin);
let getNotificationURLFor = function(messages) {
if (!messages)
@ -800,7 +800,7 @@ var AlertsHelper = {
// If we have a manifest URL, get the icon and title from the manifest
// to prevent spoofing.
let app = DOMApplicationRegistry.getAppByManifestURL(manifestUrl);
DOMApplicationRegistry.getManifestFor(app.origin, function(aManifest) {
DOMApplicationRegistry.getManifestFor(manifestUrl, function(aManifest) {
let helper = new ManifestHelper(aManifest, app.origin);
send(helper.name, helper.iconURLForSize(128));
});
@ -893,7 +893,7 @@ var WebappsHelper = {
switch(topic) {
case "webapps-launch":
DOMApplicationRegistry.getManifestFor(json.origin, function(aManifest) {
DOMApplicationRegistry.getManifestFor(json.manifestURL, function(aManifest) {
if (!aManifest)
return;

View File

@ -251,7 +251,7 @@ ContentPermissionPrompt.prototype = {
// When it's an app, get the manifest to add the l10n application name.
let app = DOMApplicationRegistry.getAppByLocalId(principal.appId);
DOMApplicationRegistry.getManifestFor(app.origin, function getManifest(aManifest) {
DOMApplicationRegistry.getManifestFor(app.manifestURL, function getManifest(aManifest) {
let helper = new ManifestHelper(aManifest, app.origin);
details.appName = helper.name;
browser.shell.sendChromeEvent(details);

View File

@ -1201,7 +1201,7 @@ this.DOMApplicationRegistry = {
}
// We need to get the old manifest to unregister web activities.
this.getManifestFor(app.origin, (function(aOldManifest) {
this.getManifestFor(aManifestURL, (function(aOldManifest) {
debug("Old manifest: " + JSON.stringify(aOldManifest));
// Move the application.zip and manifest.webapp files out of TmpD
let tmpDir = FileUtils.getDir("TmpD", ["webapps", id], true, true);
@ -1240,7 +1240,7 @@ this.DOMApplicationRegistry = {
Services.obs.notifyObservers(zipFile, "flush-cache-entry", null);
// Get the manifest, and set properties.
this.getManifestFor(app.origin, (function(aData) {
this.getManifestFor(aManifestURL, (function(aData) {
debug("New manifest: " + JSON.stringify(aData));
app.downloading = false;
app.downloadAvailable = false;
@ -1993,16 +1993,8 @@ this.DOMApplicationRegistry = {
let app = aData.app;
app.removable = true;
let origin = Services.io.newURI(app.origin, null, null);
let manifestURL = origin.resolve(app.manifestURL);
let id = this._appId(app.origin);
let localId = this.getAppLocalIdByManifestURL(manifestURL);
// For packaged apps, we need to get the id from the manifestURL.
if (localId && !id) {
id = this._appIdForManifestURL(manifestURL);
}
let id = this._appIdForManifestURL(app.manifestURL);
let localId = this.getAppLocalIdByManifestURL(app.manifestURL);
// Installing an application again is considered as an update.
if (id) {
@ -2137,14 +2129,6 @@ this.DOMApplicationRegistry = {
return id;
},
_appId: function(aURI) {
for (let id in this.webapps) {
if (this.webapps[id].origin == aURI)
return id;
}
return null;
},
_appIdForManifestURL: function(aURI) {
for (let id in this.webapps) {
if (this.webapps[id].manifestURL == aURI)
@ -2936,11 +2920,11 @@ this.DOMApplicationRegistry = {
}).bind(this));
},
getManifestFor: function(aOrigin, aCallback) {
getManifestFor: function(aManifestURL, aCallback) {
if (!aCallback)
return;
let id = this._appId(aOrigin);
let id = this._appIdForManifestURL(aManifestURL);
let app = this.webapps[id];
if (!id || (app.installState == "pending" && !app.retryingDownload)) {
aCallback(null);

View File

@ -65,6 +65,7 @@ import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.view.animation.Interpolator;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
@ -266,7 +267,7 @@ abstract public class BrowserApp extends GeckoApp
case KeyEvent.KEYCODE_BUTTON_Y:
// Toggle/focus the address bar on gamepad-y button.
if (mBrowserToolbar.isVisible()) {
if (isDynamicToolbarEnabled() && !mHomePager.isVisible()) {
if (isDynamicToolbarEnabled() && !isHomePagerVisible()) {
if (mLayerView != null) {
mLayerView.getLayerMarginsAnimator().hideMargins(false);
mLayerView.requestFocus();
@ -421,7 +422,11 @@ abstract public class BrowserApp extends GeckoApp
// If we get a gamepad panning MotionEvent while the focus is not on the layerview,
// put the focus on the layerview and carry on
if (mLayerView != null && !mLayerView.hasFocus() && GamepadUtils.isPanningControl(event)) {
if (mHomePager.isVisible()) {
if (mHomePager == null) {
return false;
}
if (isHomePagerVisible()) {
mLayerView.requestFocus();
} else {
mHomePager.requestFocus();
@ -431,7 +436,6 @@ abstract public class BrowserApp extends GeckoApp
}
});
mHomePager = (HomePager) findViewById(R.id.home_pager);
mHomePagerContainer = findViewById(R.id.home_pager_container);
mBrowserSearchContainer = findViewById(R.id.search_container);
@ -843,7 +847,7 @@ abstract public class BrowserApp extends GeckoApp
@Override
public void onMetricsChanged(ImmutableViewportMetrics aMetrics) {
if (mHomePager.isVisible() || mBrowserToolbar == null) {
if (isHomePagerVisible() || mBrowserToolbar == null) {
return;
}
@ -878,7 +882,7 @@ abstract public class BrowserApp extends GeckoApp
@Override
public void onPanZoomStopped() {
if (!isDynamicToolbarEnabled() || mHomePager.isVisible()) {
if (!isDynamicToolbarEnabled() || isHomePagerVisible()) {
return;
}
@ -900,7 +904,7 @@ abstract public class BrowserApp extends GeckoApp
height = mBrowserToolbar.getHeight();
}
if (!isDynamicToolbarEnabled() || mHomePager.isVisible()) {
if (!isDynamicToolbarEnabled() || isHomePagerVisible()) {
// Use aVisibleHeight here so that when the dynamic toolbar is
// enabled, the padding will animate with the toolbar becoming
// visible.
@ -1325,6 +1329,10 @@ abstract public class BrowserApp extends GeckoApp
mBrowserToolbar.cancelEdit();
}
private boolean isHomePagerVisible() {
return (mHomePager != null && mHomePager.isVisible());
}
private void openReadingList() {
Tabs.getInstance().loadUrl(ABOUT_HOME, Tabs.LOADURL_READING_LIST);
}
@ -1445,7 +1453,7 @@ abstract public class BrowserApp extends GeckoApp
}
private void showHomePagerWithAnimator(HomePager.Page page, PropertyAnimator animator) {
if (mHomePager.isVisible()) {
if (isHomePagerVisible()) {
return;
}
@ -1458,6 +1466,10 @@ abstract public class BrowserApp extends GeckoApp
mLayerView.getLayerMarginsAnimator().showMargins(true);
}
if (mHomePager == null) {
final ViewStub homePagerStub = (ViewStub) findViewById(R.id.home_pager);
mHomePager = (HomePager) homePagerStub.inflate();
}
mHomePager.show(getSupportFragmentManager(), page, animator);
}
@ -1470,7 +1482,7 @@ abstract public class BrowserApp extends GeckoApp
}
private void hideHomePagerWithAnimation(boolean animate) {
if (!mHomePager.isVisible()) {
if (!isHomePagerVisible()) {
return;
}
@ -1480,7 +1492,9 @@ abstract public class BrowserApp extends GeckoApp
}
// FIXME: do animation if animate is true
mHomePager.hide();
if (mHomePager != null) {
mHomePager.hide();
}
mBrowserToolbar.setNextFocusDownId(R.id.layer_view);

View File

@ -6,20 +6,18 @@
<!-- This file is used to include the home pager in gecko app
layout based on screen size -->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:gecko="http://schemas.android.com/apk/res-auto">
<org.mozilla.gecko.home.HomePager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:gecko="http://schemas.android.com/apk/res-auto"
android:id="@+id/home_pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/white"
android:visibility="gone">
<org.mozilla.gecko.home.HomePager android:id="@+id/home_pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/white"
android:visibility="gone">
<org.mozilla.gecko.home.TabMenuStrip android:layout_width="fill_parent"
android:layout_height="32dip"
android:background="@color/background_light"
android:layout_gravity="top"
gecko:strip="@drawable/home_tab_menu_strip"/>
<org.mozilla.gecko.home.TabMenuStrip android:layout_width="fill_parent"
android:layout_height="32dip"
android:background="@color/background_light"
android:layout_gravity="top"
gecko:strip="@drawable/home_tab_menu_strip"/>
</org.mozilla.gecko.home.HomePager>
</merge>
</org.mozilla.gecko.home.HomePager>

View File

@ -31,7 +31,11 @@
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include layout="@layout/home_pager"/>
<ViewStub android:id="@+id/home_pager"
android:layout="@layout/home_pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</FrameLayout>

View File

@ -6,22 +6,20 @@
<!-- This file is used to include the home pager in gecko app
layout based on screen size -->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:gecko="http://schemas.android.com/apk/res-auto">
<org.mozilla.gecko.home.HomePager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:gecko="http://schemas.android.com/apk/res-auto"
android:id="@+id/home_pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/white"
android:visibility="gone">
<org.mozilla.gecko.home.HomePager android:id="@+id/home_pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/white"
android:visibility="gone">
<org.mozilla.gecko.home.HomePagerTabStrip android:layout_width="fill_parent"
android:layout_height="32dip"
android:layout_gravity="top"
android:gravity="bottom"
android:background="@color/background_light"
gecko:tabIndicatorColor="@color/text_color_highlight"
android:textAppearance="@style/TextAppearance.Widget.HomePagerTabStrip"/>
<org.mozilla.gecko.home.HomePagerTabStrip android:layout_width="fill_parent"
android:layout_height="32dip"
android:layout_gravity="top"
android:gravity="bottom"
android:background="@color/background_light"
gecko:tabIndicatorColor="@color/text_color_highlight"
android:textAppearance="@style/TextAppearance.Widget.HomePagerTabStrip"/>
</org.mozilla.gecko.home.HomePager>
</merge>
</org.mozilla.gecko.home.HomePager>

View File

@ -6750,7 +6750,7 @@ var WebappsUI = {
break;
case "webapps-sync-install":
// Create a system notification allowing the user to launch the app
DOMApplicationRegistry.getManifestFor(data.origin, (function(aManifest) {
DOMApplicationRegistry.getManifestFor(data.manifestURL, (function(aManifest) {
if (!aManifest)
return;
let manifest = new ManifestHelper(aManifest, data.origin);

View File

@ -24,7 +24,6 @@
"content/media/test/test_can_play_type.html":"timed out",
"content/media/test/test_can_play_type_mpeg.html":"7 failures out of 27",
"content/media/test/test_can_play_type_no_dash.html":"",
"content/media/test/test_mediarecorder_record_stopms.html":"",
"content/media/test/test_can_play_type_ogg.html":"",
"content/media/test/test_chaining.html": "timed out",
"content/media/test/test_delay_load.html": "6 failures",
@ -35,7 +34,6 @@
"content/media/test/test_load_candidates.html": "timed out",
"content/media/test/test_load_same_resource.html": "",
"content/media/test/test_media_selection.html": "timed out",
"content/media/test/test_mediarecorder_avoid_recursion.html": "guM isn't ready on b2g, bug 903765",
"content/media/test/test_metadata.html": "",
"content/media/test/test_mozHasAudio.html": "",
"content/media/test/test_play_events.html": "Last event should be canplaythrough for gizmo.mp4 - got playing, expected canplaythrough",