зеркало из 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) {
|
||||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче