Bug 1322590 - Add and hook up ContentListener for GeckoView. r=jchen

This commit is contained in:
Dylan Roeh 2017-01-25 15:13:58 -06:00
Родитель 78e90909da
Коммит 81892271a5
9 изменённых файлов: 162 добавлений и 123 удалений

Просмотреть файл

@ -258,7 +258,6 @@ gvjar.sources += [geckoview_source_dir + 'java/org/mozilla/gecko/' + x
'GeckoThread.java',
'GeckoView.java',
'GeckoViewChrome.java',
'GeckoViewContent.java',
'GeckoViewFragment.java',
'gfx/BitmapUtils.java',
'gfx/BufferedImage.java',

Просмотреть файл

@ -0,0 +1,41 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* 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/. */
var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
var dump = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.d.bind(null, "ViewContent");
var DEBUG = false;
// This is copied from desktop's tab-content.js. See bug 1153485 about sharing this code somehow.
var DOMTitleChangedListener = {
init: function() {
addEventListener("DOMTitleChanged", this, false);
},
receiveMessage: function(message) {
if (DEBUG) {
dump("receiveMessage " + message.name);
}
},
handleEvent: function(aEvent) {
if (aEvent.originalTarget.defaultView != content) {
return;
}
if (DEBUG) {
dump("handleEvent " + aEvent.type);
}
switch (aEvent.type) {
case "DOMTitleChanged":
sendAsyncMessage("GeckoView:DOMTitleChanged", { title: content.document.title });
break;
}
},
};
DOMTitleChangedListener.init();

Просмотреть файл

@ -3,24 +3,32 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var Cc = Components.classes;
var Ci = Components.interfaces;
var Cu = Components.utils;
var Cr = Components.results;
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Log",
"resource://gre/modules/AndroidLog.jsm", "AndroidLog");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm", "Services");
function dump(msg) {
Log.d("View", msg);
}
XPCOMUtils.defineLazyModuleGetter(this, "EventDispatcher",
"resource://gre/modules/Messaging.jsm");
XPCOMUtils.defineLazyGetter(this, "GlobalEventDispatcher",
() => EventDispatcher.instance);
XPCOMUtils.defineLazyGetter(this, "WindowEventDispatcher",
() => EventDispatcher.for(window));
var dump = Cu.import("resource://gre/modules/AndroidLog.jsm", {})
.AndroidLog.d.bind(null, "View");
// GeckoView module imports.
XPCOMUtils.defineLazyModuleGetter(this, "GeckoViewContent",
"resource://gre/modules/GeckoViewContent.jsm");
var content;
function startup() {
dump("zerdatime " + Date.now() + " - geckoview chrome startup finished.");
dump("zerdatime " + Date.now() + " - geckoview chrome startup finished.");
content = new GeckoViewContent(window, document.getElementById("content"), WindowEventDispatcher);
}

Просмотреть файл

@ -29,6 +29,7 @@ chrome.jar:
content/browser.js (content/browser.js)
content/geckoview.xul (content/geckoview.xul)
content/geckoview.js (content/geckoview.js)
content/GeckoViewContent.js (content/GeckoViewContent.js)
content/PresentationView.xul (content/PresentationView.xul)
content/PresentationView.js (content/PresentationView.js)
content/bindings/checkbox.xml (content/bindings/checkbox.xml)

Просмотреть файл

@ -14,7 +14,9 @@ import org.mozilla.gecko.annotation.ReflectionTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.mozglue.JNIObject;
import org.mozilla.gecko.util.BundleEventListener;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoBundle;
import android.app.Activity;
import android.content.Context;
@ -39,10 +41,12 @@ public class GeckoView extends LayerView
private static final String DEFAULT_SHARED_PREFERENCES_FILE = "GeckoView";
private static final String LOGTAG = "GeckoView";
private static final boolean DEBUG = false;
private final EventDispatcher eventDispatcher = new EventDispatcher();
private ChromeDelegate mChromeDelegate;
private ContentDelegate mContentDelegate;
/* package */ ContentListener mContentListener;
private InputConnectionListener mInputConnectionListener;
@ -108,8 +112,31 @@ public class GeckoView extends LayerView
};
}
private class Listener implements BundleEventListener {
/* package */ void registerListeners() {
getEventDispatcher().registerUiThreadListener(this,
"GeckoView:DOMTitleChanged",
null);
}
@Override
public void handleMessage(final String event, final GeckoBundle message,
final EventCallback callback) {
if (DEBUG) {
Log.d(LOGTAG, "handleMessage: event = " + event);
}
if ("GeckoView:DOMTitleChanged".equals(event)) {
if (mContentListener != null) {
mContentListener.onTitleChanged(GeckoView.this, message.getString("title"));
}
}
}
}
protected Window window;
private boolean stateSaved;
private final Listener listener = new Listener();
public GeckoView(Context context) {
super(context);
@ -137,6 +164,7 @@ public class GeckoView extends LayerView
GeckoAppShell.setLayerView(this);
initializeView();
listener.registerListeners();
}
@Override
@ -342,10 +370,18 @@ public class GeckoView extends LayerView
/**
* Set the content callback handler.
* This will replace the current handler.
* @param content An implementation of ContentDelegate.
* @param content An implementation of ContentListener.
*/
public void setContentDelegate(ContentDelegate content) {
mContentDelegate = content;
public void setContentListener(ContentListener content) {
mContentListener = content;
}
/**
* Get the content callback handler.
* @return The current content callback handler.
*/
public ContentListener getContentListener() {
return mContentListener;
}
public static void setGeckoInterface(final BaseGeckoInterface geckoInterface) {
@ -435,43 +471,13 @@ public class GeckoView extends LayerView
public void onDebugRequest(GeckoView view, GeckoView.PromptResult result);
}
public interface ContentDelegate {
/**
* A View has started loading content from the network.
* @param view The GeckoView that initiated the callback.
* @param url The resource being loaded.
*/
public void onPageStart(GeckoView view, String url);
/**
* A View has finished loading content from the network.
* @param view The GeckoView that initiated the callback.
* @param success Whether the page loaded successfully or an error occurred.
*/
public void onPageStop(GeckoView view, boolean success);
/**
* A View is displaying content. This page could have been loaded via
* network or from the session history.
* @param view The GeckoView that initiated the callback.
*/
public void onPageShow(GeckoView view);
public interface ContentListener {
/**
* A page title was discovered in the content or updated after the content
* loaded.
* @param view The GeckoView that initiated the callback.
* @param title The title sent from the content.
*/
public void onReceivedTitle(GeckoView view, String title);
/**
* A link element was discovered in the content or updated after the content
* loaded that specifies a favicon.
* @param view The GeckoView that initiated the callback.
* @param url The href of the link element specifying the favicon.
* @param size The maximum size specified for the favicon, or -1 for any size.
*/
public void onReceivedFavicon(GeckoView view, String url, int size);
public void onTitleChanged(GeckoView view, String title);
}
}

Просмотреть файл

@ -1,51 +0,0 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* 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/. */
package org.mozilla.gecko;
public class GeckoViewContent implements GeckoView.ContentDelegate {
/**
* A View has started loading content from the network.
* @param view The GeckoView that initiated the callback.
* @param url The resource being loaded.
*/
@Override
public void onPageStart(GeckoView view, String url) {}
/**
* A View has finished loading content from the network.
* @param view The GeckoView that initiated the callback.
* @param success Whether the page loaded successfully or an error occurred.
*/
@Override
public void onPageStop(GeckoView view, boolean success) {}
/**
* A View is displaying content. This page could have been loaded via
* network or from the session history.
* @param view The GeckoView that initiated the callback.
*/
@Override
public void onPageShow(GeckoView view) {}
/**
* A page title was discovered in the content or updated after the content
* loaded.
* @param view The GeckoView that initiated the callback.
* @param title The title sent from the content.
*/
@Override
public void onReceivedTitle(GeckoView view, String title) {}
/**
* A link element was discovered in the content or updated after the content
* loaded that specifies a favicon.
* @param view The GeckoView that initiated the callback.
* @param url The href of the link element specifying the favicon.
* @param size The maximum size specified for the favicon, or -1 for any size.
*/
@Override
public void onReceivedFavicon(GeckoView view, String url, int size) {}
}

Просмотреть файл

@ -34,7 +34,7 @@ public class GeckoViewActivity extends Activity {
mGeckoView = (GeckoView) findViewById(R.id.gecko_view);
mGeckoView.setChromeDelegate(new MyGeckoViewChrome());
mGeckoView.setContentDelegate(new MyGeckoViewContent());
mGeckoView.setContentListener(new MyGeckoViewContent());
}
@Override
@ -89,30 +89,10 @@ public class GeckoViewActivity extends Activity {
}
}
private class MyGeckoViewContent implements GeckoView.ContentDelegate {
private class MyGeckoViewContent implements GeckoView.ContentListener {
@Override
public void onPageStart(GeckoView view, String url) {
}
@Override
public void onPageStop(GeckoView view, boolean success) {
}
@Override
public void onPageShow(GeckoView view) {
}
@Override
public void onReceivedTitle(GeckoView view, String title) {
Log.i(LOGTAG, "Received a title: " + title);
}
@Override
public void onReceivedFavicon(GeckoView view, String url, int size) {
Log.i(LOGTAG, "Received a favicon URL: " + url);
public void onTitleChanged(GeckoView view, String title) {
Log.i(LOGTAG, "Content title changed to " + title);
}
}
}

Просмотреть файл

@ -0,0 +1,50 @@
/* 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";
this.EXPORTED_SYMBOLS = ["GeckoViewContent"];
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
var dump = Cu.import("resource://gre/modules/AndroidLog.jsm", {})
.AndroidLog.d.bind(null, "ViewContent");
var DEBUG = false;
class GeckoViewContent {
constructor(_window, _browser, _windowEventDispatcher) {
this.window = _window;
this.browser = _browser;
this.windowEventDispatcher = _windowEventDispatcher;
this.window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow = this;
this.messageManager.loadFrameScript("chrome://browser/content/GeckoViewContent.js", true);
this.messageManager.addMessageListener("GeckoView:DOMTitleChanged", this);
}
get messageManager() {
return this.browser.messageManager;
}
handleEvent(event) {
if (DEBUG) {
dump("handleEvent: event.type=" + event.type);
}
}
// Message manager event handler.
receiveMessage(msg) {
if (DEBUG) {
dump("receiveMessage " + msg.name);
}
switch (msg.name) {
case "GeckoView:DOMTitleChanged":
this.windowEventDispatcher.sendRequest({ type: "GeckoView:DOMTitleChanged", title: msg.data.title });
break;
}
}
}

Просмотреть файл

@ -30,3 +30,8 @@ EXTRA_JS_MODULES += [
'SSLExceptions.jsm',
'WebsiteMetadata.jsm'
]
# GeckoView-sepcific modules added separately.
EXTRA_JS_MODULES += [
'GeckoViewContent.jsm'
]