diff --git a/browser/actors/moz.build b/browser/actors/moz.build index 28c981625a7f..2b3a706d0e49 100644 --- a/browser/actors/moz.build +++ b/browser/actors/moz.build @@ -50,8 +50,6 @@ FINAL_TARGET_FILES.actors += [ "BrowserTabParent.jsm", "ClickHandlerChild.jsm", "ClickHandlerParent.jsm", - "ContentMetaChild.jsm", - "ContentMetaParent.jsm", "ContentSearchChild.jsm", "ContentSearchParent.jsm", "ContextMenuChild.jsm", diff --git a/browser/base/content/tabbrowser.js b/browser/base/content/tabbrowser.js index 59a0c9fc790c..767fb8a86421 100644 --- a/browser/base/content/tabbrowser.js +++ b/browser/base/content/tabbrowser.js @@ -6093,6 +6093,17 @@ once: true, }); }); + + this.addEventListener("pageinfo", event => { + let browser = event.originalTarget; + let tab = this.getTabForBrowser(browser); + if (!tab) { + return; + } + + const { url, description, previewImageURL } = event.detail; + this.setPageInfo(url, description, previewImageURL); + }); }, setSuccessor(aTab, successorTab) { diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm index d5494704af56..6b6197404271 100644 --- a/browser/components/BrowserGlue.jsm +++ b/browser/components/BrowserGlue.jsm @@ -400,22 +400,6 @@ let JSWINDOWACTORS = { allFrames: true, }, - // Collects description and icon information from meta tags. - ContentMeta: { - parent: { - moduleURI: "resource:///actors/ContentMetaParent.jsm", - }, - - child: { - moduleURI: "resource:///actors/ContentMetaChild.jsm", - events: { - DOMMetaAdded: {}, - }, - }, - - messageManagerGroups: ["browsers"], - }, - ContentSearch: { parent: { moduleURI: "resource:///actors/ContentSearchParent.jsm", diff --git a/mobile/android/geckoview/api.txt b/mobile/android/geckoview/api.txt index 3bec8b22f4f9..e3d9585a2f5d 100644 --- a/mobile/android/geckoview/api.txt +++ b/mobile/android/geckoview/api.txt @@ -901,6 +901,7 @@ package org.mozilla.geckoview { method @UiThread default public void onMetaViewportFitChange(@NonNull GeckoSession, @NonNull String); method @UiThread default public void onPaintStatusReset(@NonNull GeckoSession); method @UiThread default public void onPointerIconChange(@NonNull GeckoSession, @NonNull PointerIcon); + method @UiThread default public void onPreviewImage(@NonNull GeckoSession, @NonNull String); method @UiThread default public void onShowDynamicToolbar(@NonNull GeckoSession); method @Nullable @UiThread default public GeckoResult onSlowScript(@NonNull GeckoSession, @NonNull String); method @UiThread default public void onTitleChange(@NonNull GeckoSession, @Nullable String); diff --git a/mobile/android/geckoview/src/androidTest/assets/www/metatags.html b/mobile/android/geckoview/src/androidTest/assets/www/metatags.html new file mode 100644 index 000000000000..61639194a85c --- /dev/null +++ b/mobile/android/geckoview/src/androidTest/assets/www/metatags.html @@ -0,0 +1,17 @@ + + + + + MetaTags + + + + + + + + + + + + diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt index 4eccb31d0a7b..0d6cff17b3be 100644 --- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt @@ -53,6 +53,7 @@ open class BaseSessionTest(noErrorCollector: Boolean = false) { const val INVALID_URI = "not a valid uri" const val LINKS_HTML_PATH = "/assets/www/links.html" const val LOREM_IPSUM_HTML_PATH = "/assets/www/loremIpsum.html" + const val METATAGS_PATH = "/assets/www/metatags.html" const val MOUSE_TO_RELOAD_HTML_PATH = "/assets/www/mouseToReload.html" const val NEW_SESSION_CHILD_HTML_PATH = "/assets/www/newSession_child.html" const val NEW_SESSION_HTML_PATH = "/assets/www/newSession.html" diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ContentDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ContentDelegateTest.kt index 99395d19a54a..cd7b840634c8 100644 --- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ContentDelegateTest.kt +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ContentDelegateTest.kt @@ -274,6 +274,16 @@ class ContentDelegateTest : BaseSessionTest() { }) } + @Test fun previewImage() { + mainSession.loadTestPath(METATAGS_PATH) + mainSession.waitUntilCalled(object : ContentDelegate, ProgressDelegate { + @AssertCalled(count = 1) + override fun onPreviewImage(session: GeckoSession, previewImageUrl: String) { + assertThat("Preview image should match", previewImageUrl, equalTo("https://test.com/og-image-url")) + } + }) + } + @Test fun viewportFit() { mainSession.loadTestPath(VIEWPORT_PATH) mainSession.waitUntilCalled(object : ContentDelegate, ProgressDelegate { diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java index 6e9263e7b84e..661123d93c98 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java @@ -377,6 +377,7 @@ public class GeckoSession { "GeckoView:WebAppManifest", "GeckoView:FirstContentfulPaint", "GeckoView:PaintStatusReset", + "GeckoView:PreviewImage", }) { @Override public void handleMessage( @@ -431,6 +432,8 @@ public class GeckoSession { delegate.onFirstContentfulPaint(GeckoSession.this); } else if ("GeckoView:PaintStatusReset".equals(event)) { delegate.onPaintStatusReset(GeckoSession.this); + } else if ("GeckoView:PreviewImage".equals(event)) { + delegate.onPreviewImage(GeckoSession.this, message.getString("previewImageUrl")); } } }; @@ -2859,6 +2862,16 @@ public class GeckoSession { @UiThread default void onTitleChange(@NonNull final GeckoSession session, @Nullable final String title) {} + /** + * A preview image was discovered in the content after the content loaded. + * + * @param session The GeckoSession that initiated the callback. + * @param previewImageUrl The preview image URL sent from the content. + */ + @UiThread + default void onPreviewImage( + @NonNull final GeckoSession session, @NonNull final String previewImageUrl) {} + /** * A page has requested focus. Note that window.focus() in content will not result in this being * called. diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md index d3c399144593..38c672124eb3 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md @@ -26,6 +26,8 @@ exclude: true protection permissions in private browsing). - Deprecated [`GeckoRuntimeSettings.Builder.enterpiseRootsEnabled`][95.7] due to typo. - Added [`GeckoRuntimeSettings.Builder.enterpriseRootsEnabled`][95.8] to replace [`GeckoRuntimeSettings.Builder.enterpiseRootsEnabled`][95.7]. +- Added [`GeckoSession.ContentDelegate.onPreviewImage()`][95.9] to notify + the application of a preview image URL. [95.1]: {{javadoc_uri}}/GeckoSession.ContentDelegate.html#onPointerIconChange-org.mozilla.geckoview.GeckoSession-android.view.PointerIcon- [95.2]: {{javadoc_uri}/ContentBlockingController.html @@ -35,6 +37,7 @@ exclude: true [95.6]: {{javadoc_uri}/StorageController.html#setPrivateBrowsingPermanentPermission-org.mozilla.geckoview.GeckoSession.PermissionDelegate.ContentPermission-int- [95.7]: {{javadoc_uri}}/GeckoRuntimeSettings.Builder.html#enterpiseRootsEnabled-boolean- [95.8]: {{javadoc_uri}}/GeckoRuntimeSettings.Builder.html#enterpriseRootsEnabled-boolean- +[95.9]: {{javadoc_uri}}/GeckoSession.ContentDelegate.html#onPreviewImage-org.mozilla.geckoview.GeckoSession-java.lang.String- ## v94 - Extended [`Autocomplete`][78.7] API to support credit card saving. @@ -1069,4 +1072,4 @@ to allow adding gecko profiler markers. [65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport-android.content.Context-android.os.Bundle-java.lang.String- [65.25]: {{javadoc_uri}}/GeckoResult.html -[api-version]: efde9e11f6249cf145903d7c6e317d5c17be8d1e +[api-version]: d44de923c2ba7fb152398b9001d26b4ed2689138 diff --git a/mobile/android/modules/geckoview/GeckoViewContent.jsm b/mobile/android/modules/geckoview/GeckoViewContent.jsm index 3024677e9f3f..955f1d6e197f 100644 --- a/mobile/android/modules/geckoview/GeckoViewContent.jsm +++ b/mobile/android/modules/geckoview/GeckoViewContent.jsm @@ -56,6 +56,7 @@ class GeckoViewContent extends GeckoViewModule { this.window.addEventListener("DOMWindowClose", this); this.window.addEventListener("pagetitlechanged", this); + this.window.addEventListener("pageinfo", this); Services.obs.addObserver(this, "oop-frameloader-crashed"); Services.obs.addObserver(this, "ipc:content-shutdown"); @@ -80,6 +81,7 @@ class GeckoViewContent extends GeckoViewModule { this.window.removeEventListener("DOMWindowClose", this); this.window.removeEventListener("pagetitlechanged", this); + this.window.removeEventListener("pageinfo", this); Services.obs.removeObserver(this, "oop-frameloader-crashed"); Services.obs.removeObserver(this, "ipc:content-shutdown"); @@ -208,6 +210,14 @@ class GeckoViewContent extends GeckoViewModule { type: "GeckoView:DOMWindowClose", }); break; + case "pageinfo": + if (aEvent.detail.previewImageURL) { + this.eventDispatcher.sendRequest({ + type: "GeckoView:PreviewImage", + previewImageUrl: aEvent.detail.previewImageURL, + }); + } + break; } } diff --git a/browser/actors/ContentMetaChild.jsm b/toolkit/actors/ContentMetaChild.jsm similarity index 100% rename from browser/actors/ContentMetaChild.jsm rename to toolkit/actors/ContentMetaChild.jsm diff --git a/browser/actors/ContentMetaParent.jsm b/toolkit/actors/ContentMetaParent.jsm similarity index 59% rename from browser/actors/ContentMetaParent.jsm rename to toolkit/actors/ContentMetaParent.jsm index ddad35883b39..5d350754cd5a 100644 --- a/browser/actors/ContentMetaParent.jsm +++ b/toolkit/actors/ContentMetaParent.jsm @@ -11,14 +11,16 @@ class ContentMetaParent extends JSWindowActorParent { if (message.name == "Meta:SetPageInfo") { let browser = this.manager.browsingContext.top.embedderElement; if (browser) { - let gBrowser = browser.ownerGlobal.gBrowser; - if (gBrowser) { - gBrowser.setPageInfo( - message.data.url, - message.data.description, - message.data.previewImageURL - ); - } + let event = new browser.ownerGlobal.CustomEvent("pageinfo", { + bubbles: true, + cancelable: false, + detail: { + url: message.data.url, + description: message.data.description, + previewImageURL: message.data.previewImageURL, + }, + }); + browser.dispatchEvent(event); } } } diff --git a/toolkit/actors/moz.build b/toolkit/actors/moz.build index 40729d7210bc..30a8d41bfa17 100644 --- a/toolkit/actors/moz.build +++ b/toolkit/actors/moz.build @@ -37,6 +37,8 @@ FINAL_TARGET_FILES.actors += [ "BackgroundThumbnailsChild.jsm", "BrowserElementChild.jsm", "BrowserElementParent.jsm", + "ContentMetaChild.jsm", + "ContentMetaParent.jsm", "ControllersChild.jsm", "ControllersParent.jsm", "DateTimePickerChild.jsm", diff --git a/toolkit/modules/ActorManagerParent.jsm b/toolkit/modules/ActorManagerParent.jsm index da76e00beebb..aa642775be9d 100644 --- a/toolkit/modules/ActorManagerParent.jsm +++ b/toolkit/modules/ActorManagerParent.jsm @@ -189,6 +189,21 @@ let JSWINDOWACTORS = { allFrames: true, }, + ContentMeta: { + parent: { + moduleURI: "resource://gre/actors/ContentMetaParent.jsm", + }, + + child: { + moduleURI: "resource://gre/actors/ContentMetaChild.jsm", + events: { + DOMMetaAdded: {}, + }, + }, + + messageManagerGroups: ["browsers"], + }, + Controllers: { parent: { moduleURI: "resource://gre/actors/ControllersParent.jsm",