зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1509266 - [1.3] Extend element information passed to ContentDelegate.onContextMenu. r=snorp,agi
Differential Revision: https://phabricator.services.mozilla.com/D12967 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
1f285bb075
Коммит
29411ef725
|
@ -257,31 +257,37 @@ class GeckoViewContentChild extends GeckoViewChildModule {
|
||||||
|
|
||||||
switch (aEvent.type) {
|
switch (aEvent.type) {
|
||||||
case "contextmenu":
|
case "contextmenu":
|
||||||
function nearestParentHref(node) {
|
function nearestParentAttribute(aNode, aAttribute) {
|
||||||
while (node && !node.href) {
|
while (aNode && aNode.hasAttribute &&
|
||||||
node = node.parentNode;
|
!aNode.hasAttribute(aAttribute)) {
|
||||||
|
aNode = aNode.parentNode;
|
||||||
}
|
}
|
||||||
return node && node.href;
|
return aNode && aNode.getAttribute && aNode.getAttribute(aAttribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
const node = aEvent.composedTarget;
|
const node = aEvent.composedTarget;
|
||||||
const hrefNode = nearestParentHref(node);
|
const uri = nearestParentAttribute(node, "href");
|
||||||
|
const title = nearestParentAttribute(node, "title");
|
||||||
|
const alt = nearestParentAttribute(node, "alt");
|
||||||
const elementType = ChromeUtils.getClassName(node);
|
const elementType = ChromeUtils.getClassName(node);
|
||||||
const isImage = elementType === "HTMLImageElement";
|
const isImage = elementType === "HTMLImageElement";
|
||||||
const isMedia = elementType === "HTMLVideoElement" ||
|
const isMedia = elementType === "HTMLVideoElement" ||
|
||||||
elementType === "HTMLAudioElement";
|
elementType === "HTMLAudioElement";
|
||||||
|
const elementSrc = (isImage || isMedia) && (node.currentSrc || node.src);
|
||||||
|
|
||||||
if (hrefNode || isImage || isMedia) {
|
if (uri || isImage || isMedia) {
|
||||||
this.eventDispatcher.sendRequest({
|
const msg = {
|
||||||
type: "GeckoView:ContextMenu",
|
type: "GeckoView:ContextMenu",
|
||||||
screenX: aEvent.screenX,
|
screenX: aEvent.screenX,
|
||||||
screenY: aEvent.screenY,
|
screenY: aEvent.screenY,
|
||||||
uri: hrefNode,
|
uri,
|
||||||
|
title,
|
||||||
|
alt,
|
||||||
elementType,
|
elementType,
|
||||||
elementSrc: (isImage || isMedia)
|
elementSrc: elementSrc || null,
|
||||||
? node.currentSrc || node.src
|
};
|
||||||
: null,
|
|
||||||
});
|
this.eventDispatcher.sendRequest(msg);
|
||||||
aEvent.preventDefault();
|
aEvent.preventDefault();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -21,5 +21,8 @@
|
||||||
classifier.
|
classifier.
|
||||||
- Added a `protected` empty constructor to all field-only classes so that apps
|
- Added a `protected` empty constructor to all field-only classes so that apps
|
||||||
can mock these classes in tests.
|
can mock these classes in tests.
|
||||||
|
- Added `ContentDelegate.ContextElement` to extend the information passed to
|
||||||
|
`ContentDelegate#onContextMenu`. Extended information includes the element's
|
||||||
|
title and alt attributes.
|
||||||
|
|
||||||
[api-version]: 723adca536354bfa81afb83da5045ea6de8aa602
|
[api-version]: 8cfd04a09e7a242b3da22ccdd55c88a2aca2ba6d
|
||||||
|
|
|
@ -322,20 +322,22 @@ package org.mozilla.geckoview {
|
||||||
|
|
||||||
public static interface GeckoSession.ContentDelegate {
|
public static interface GeckoSession.ContentDelegate {
|
||||||
method public void onCloseRequest(org.mozilla.geckoview.GeckoSession);
|
method public void onCloseRequest(org.mozilla.geckoview.GeckoSession);
|
||||||
method public void onContextMenu(org.mozilla.geckoview.GeckoSession, int, int, java.lang.String, int, java.lang.String);
|
method public void onContextMenu(org.mozilla.geckoview.GeckoSession, int, int, org.mozilla.geckoview.GeckoSession.ContentDelegate.ContextElement);
|
||||||
method public void onCrash(org.mozilla.geckoview.GeckoSession);
|
method public void onCrash(org.mozilla.geckoview.GeckoSession);
|
||||||
method public void onExternalResponse(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.GeckoSession.WebResponseInfo);
|
method public void onExternalResponse(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.GeckoSession.WebResponseInfo);
|
||||||
method public void onFirstComposite(org.mozilla.geckoview.GeckoSession);
|
method public void onFirstComposite(org.mozilla.geckoview.GeckoSession);
|
||||||
method public void onFocusRequest(org.mozilla.geckoview.GeckoSession);
|
method public void onFocusRequest(org.mozilla.geckoview.GeckoSession);
|
||||||
method public void onFullScreen(org.mozilla.geckoview.GeckoSession, boolean);
|
method public void onFullScreen(org.mozilla.geckoview.GeckoSession, boolean);
|
||||||
method public void onTitleChange(org.mozilla.geckoview.GeckoSession, java.lang.String);
|
method public void onTitleChange(org.mozilla.geckoview.GeckoSession, java.lang.String);
|
||||||
field public static final int ELEMENT_TYPE_AUDIO = 3;
|
|
||||||
field public static final int ELEMENT_TYPE_IMAGE = 1;
|
|
||||||
field public static final int ELEMENT_TYPE_NONE = 0;
|
|
||||||
field public static final int ELEMENT_TYPE_VIDEO = 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface GeckoSession.ContentDelegate.ElementType implements java.lang.annotation.Annotation {
|
public static final class GeckoSession.ContentDelegate.ContextElement {
|
||||||
|
ctor protected ContextElement(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
|
||||||
|
field public final java.lang.String altText;
|
||||||
|
field public final java.lang.String linkUri;
|
||||||
|
field public final java.lang.String srcUri;
|
||||||
|
field public final java.lang.String title;
|
||||||
|
field public final int type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class GeckoSession.FinderResult {
|
public static final class GeckoSession.FinderResult {
|
||||||
|
|
|
@ -364,15 +364,19 @@ public class GeckoSession implements Parcelable {
|
||||||
close();
|
close();
|
||||||
delegate.onCrash(GeckoSession.this);
|
delegate.onCrash(GeckoSession.this);
|
||||||
} else if ("GeckoView:ContextMenu".equals(event)) {
|
} else if ("GeckoView:ContextMenu".equals(event)) {
|
||||||
final int type = getContentElementType(
|
final ContentDelegate.ContextElement elem =
|
||||||
message.getString("elementType"));
|
new ContentDelegate.ContextElement(
|
||||||
|
message.getString("uri"),
|
||||||
|
message.getString("title"),
|
||||||
|
message.getString("alt"),
|
||||||
|
message.getString("elementType"),
|
||||||
|
message.getString("elementSrc"));
|
||||||
|
|
||||||
delegate.onContextMenu(GeckoSession.this,
|
delegate.onContextMenu(GeckoSession.this,
|
||||||
message.getInt("screenX"),
|
message.getInt("screenX"),
|
||||||
message.getInt("screenY"),
|
message.getInt("screenY"),
|
||||||
message.getString("uri"),
|
elem);
|
||||||
type,
|
|
||||||
message.getString("elementSrc"));
|
|
||||||
} else if ("GeckoView:DOMTitleChanged".equals(event)) {
|
} else if ("GeckoView:DOMTitleChanged".equals(event)) {
|
||||||
delegate.onTitleChange(GeckoSession.this,
|
delegate.onTitleChange(GeckoSession.this,
|
||||||
message.getString("title"));
|
message.getString("title"));
|
||||||
|
@ -2498,17 +2502,6 @@ public class GeckoSession implements Parcelable {
|
||||||
void onSecurityChange(GeckoSession session, SecurityInformation securityInfo);
|
void onSecurityChange(GeckoSession session, SecurityInformation securityInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getContentElementType(final String name) {
|
|
||||||
if ("HTMLImageElement".equals(name)) {
|
|
||||||
return ContentDelegate.ELEMENT_TYPE_IMAGE;
|
|
||||||
} else if ("HTMLVideoElement".equals(name)) {
|
|
||||||
return ContentDelegate.ELEMENT_TYPE_VIDEO;
|
|
||||||
} else if ("HTMLAudioElement".equals(name)) {
|
|
||||||
return ContentDelegate.ELEMENT_TYPE_AUDIO;
|
|
||||||
}
|
|
||||||
return ContentDelegate.ELEMENT_TYPE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WebResponseInfo contains information about a single web response.
|
* WebResponseInfo contains information about a single web response.
|
||||||
*/
|
*/
|
||||||
|
@ -2557,14 +2550,6 @@ public class GeckoSession implements Parcelable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ContentDelegate {
|
public interface ContentDelegate {
|
||||||
@IntDef({ELEMENT_TYPE_NONE, ELEMENT_TYPE_IMAGE, ELEMENT_TYPE_VIDEO,
|
|
||||||
ELEMENT_TYPE_AUDIO})
|
|
||||||
/* package */ @interface ElementType {}
|
|
||||||
static final int ELEMENT_TYPE_NONE = 0;
|
|
||||||
static final int ELEMENT_TYPE_IMAGE = 1;
|
|
||||||
static final int ELEMENT_TYPE_VIDEO = 2;
|
|
||||||
static final int ELEMENT_TYPE_AUDIO = 3;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A page title was discovered in the content or updated after the content
|
* A page title was discovered in the content or updated after the content
|
||||||
* loaded.
|
* loaded.
|
||||||
|
@ -2596,6 +2581,69 @@ public class GeckoSession implements Parcelable {
|
||||||
*/
|
*/
|
||||||
void onFullScreen(GeckoSession session, boolean fullScreen);
|
void onFullScreen(GeckoSession session, boolean fullScreen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Element details for onContextMenu callbacks.
|
||||||
|
*/
|
||||||
|
public static final class ContextElement {
|
||||||
|
@IntDef({TYPE_NONE, TYPE_IMAGE, TYPE_VIDEO, TYPE_AUDIO})
|
||||||
|
/* package */ @interface Type {}
|
||||||
|
static final int TYPE_NONE = 0;
|
||||||
|
static final int TYPE_IMAGE = 1;
|
||||||
|
static final int TYPE_VIDEO = 2;
|
||||||
|
static final int TYPE_AUDIO = 3;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The link URI (href) of the element.
|
||||||
|
*/
|
||||||
|
public final @Nullable String linkUri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The title text of the element.
|
||||||
|
*/
|
||||||
|
public final @Nullable String title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The alternative text (alt) for the element.
|
||||||
|
*/
|
||||||
|
public final @Nullable String altText;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the element.
|
||||||
|
* One of the {@link ContextElement#TYPE_NONE} flags.
|
||||||
|
*/
|
||||||
|
public final @Type int type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The source URI (src) of the element.
|
||||||
|
* Set for (nested) media elements.
|
||||||
|
*/
|
||||||
|
public final @Nullable String srcUri;
|
||||||
|
|
||||||
|
protected ContextElement(
|
||||||
|
final @Nullable String linkUri,
|
||||||
|
final @Nullable String title,
|
||||||
|
final @Nullable String altText,
|
||||||
|
final @NonNull String typeStr,
|
||||||
|
final @Nullable String srcUri) {
|
||||||
|
this.linkUri = linkUri;
|
||||||
|
this.title = title;
|
||||||
|
this.altText = altText;
|
||||||
|
this.type = getType(typeStr);
|
||||||
|
this.srcUri = srcUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getType(final String name) {
|
||||||
|
if ("HTMLImageElement".equals(name)) {
|
||||||
|
return TYPE_IMAGE;
|
||||||
|
} else if ("HTMLVideoElement".equals(name)) {
|
||||||
|
return TYPE_VIDEO;
|
||||||
|
} else if ("HTMLAudioElement".equals(name)) {
|
||||||
|
return TYPE_AUDIO;
|
||||||
|
}
|
||||||
|
return TYPE_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A user has initiated the context menu via long-press.
|
* A user has initiated the context menu via long-press.
|
||||||
|
@ -2605,16 +2653,11 @@ public class GeckoSession implements Parcelable {
|
||||||
* @param session The GeckoSession that initiated the callback.
|
* @param session The GeckoSession that initiated the callback.
|
||||||
* @param screenX The screen coordinates of the press.
|
* @param screenX The screen coordinates of the press.
|
||||||
* @param screenY The screen coordinates of the press.
|
* @param screenY The screen coordinates of the press.
|
||||||
* @param uri The URI of the pressed link, set for links and
|
* @param element The details for the pressed element.
|
||||||
* image-links.
|
|
||||||
* @param elementType The type of the pressed element.
|
|
||||||
* One of the {@link ContentDelegate#ELEMENT_TYPE_NONE} flags.
|
|
||||||
* @param elementSrc The source URI of the pressed element, set for
|
|
||||||
* (nested) images and media elements.
|
|
||||||
*/
|
*/
|
||||||
void onContextMenu(GeckoSession session, int screenX, int screenY,
|
void onContextMenu(@NonNull GeckoSession session,
|
||||||
String uri, @ElementType int elementType,
|
int screenX, int screenY,
|
||||||
String elementSrc);
|
@NonNull ContextElement element);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is fired when there is a response that cannot be handled
|
* This is fired when there is a response that cannot be handled
|
||||||
|
|
Загрузка…
Ссылка в новой задаче