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:
Eugen Sawin 2018-11-27 20:29:04 +00:00
Родитель 1f285bb075
Коммит 29411ef725
4 изменённых файлов: 106 добавлений и 52 удалений

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

@ -257,31 +257,37 @@ class GeckoViewContentChild extends GeckoViewChildModule {
switch (aEvent.type) {
case "contextmenu":
function nearestParentHref(node) {
while (node && !node.href) {
node = node.parentNode;
function nearestParentAttribute(aNode, aAttribute) {
while (aNode && aNode.hasAttribute &&
!aNode.hasAttribute(aAttribute)) {
aNode = aNode.parentNode;
}
return node && node.href;
return aNode && aNode.getAttribute && aNode.getAttribute(aAttribute);
}
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 isImage = elementType === "HTMLImageElement";
const isMedia = elementType === "HTMLVideoElement" ||
elementType === "HTMLAudioElement";
const elementSrc = (isImage || isMedia) && (node.currentSrc || node.src);
if (hrefNode || isImage || isMedia) {
this.eventDispatcher.sendRequest({
if (uri || isImage || isMedia) {
const msg = {
type: "GeckoView:ContextMenu",
screenX: aEvent.screenX,
screenY: aEvent.screenY,
uri: hrefNode,
uri,
title,
alt,
elementType,
elementSrc: (isImage || isMedia)
? node.currentSrc || node.src
: null,
});
elementSrc: elementSrc || null,
};
this.eventDispatcher.sendRequest(msg);
aEvent.preventDefault();
}
break;

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

@ -21,5 +21,8 @@
classifier.
- Added a `protected` empty constructor to all field-only classes so that apps
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 {
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 onExternalResponse(org.mozilla.geckoview.GeckoSession, org.mozilla.geckoview.GeckoSession.WebResponseInfo);
method public void onFirstComposite(org.mozilla.geckoview.GeckoSession);
method public void onFocusRequest(org.mozilla.geckoview.GeckoSession);
method public void onFullScreen(org.mozilla.geckoview.GeckoSession, boolean);
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 {

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

@ -364,15 +364,19 @@ public class GeckoSession implements Parcelable {
close();
delegate.onCrash(GeckoSession.this);
} else if ("GeckoView:ContextMenu".equals(event)) {
final int type = getContentElementType(
message.getString("elementType"));
final ContentDelegate.ContextElement elem =
new ContentDelegate.ContextElement(
message.getString("uri"),
message.getString("title"),
message.getString("alt"),
message.getString("elementType"),
message.getString("elementSrc"));
delegate.onContextMenu(GeckoSession.this,
message.getInt("screenX"),
message.getInt("screenY"),
message.getString("uri"),
type,
message.getString("elementSrc"));
elem);
} else if ("GeckoView:DOMTitleChanged".equals(event)) {
delegate.onTitleChange(GeckoSession.this,
message.getString("title"));
@ -2498,17 +2502,6 @@ public class GeckoSession implements Parcelable {
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.
*/
@ -2557,14 +2550,6 @@ public class GeckoSession implements Parcelable {
}
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
* loaded.
@ -2596,6 +2581,69 @@ public class GeckoSession implements Parcelable {
*/
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.
@ -2605,16 +2653,11 @@ public class GeckoSession implements Parcelable {
* @param session The GeckoSession that initiated the callback.
* @param screenX 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
* 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.
* @param element The details for the pressed element.
*/
void onContextMenu(GeckoSession session, int screenX, int screenY,
String uri, @ElementType int elementType,
String elementSrc);
void onContextMenu(@NonNull GeckoSession session,
int screenX, int screenY,
@NonNull ContextElement element);
/**
* This is fired when there is a response that cannot be handled