package org.limewire.ui.swing.browser;
import java.net.URI;
import java.net.URISyntaxException;
import org.limewire.concurrent.ManagedThread;
import org.limewire.core.api.magnet.MagnetFactory;
import org.limewire.core.api.magnet.MagnetLink;
import org.limewire.ui.swing.util.MagnetHandler;
import org.limewire.ui.swing.util.NativeLaunchUtils;
import org.limewire.util.URIUtils;
import org.mozilla.browser.XPCOMUtils;
import org.mozilla.interfaces.nsIDOMEventTarget;
import org.mozilla.interfaces.nsIDOMWindow2;
import org.mozilla.interfaces.nsIWebBrowserChrome;
import org.w3c.dom.Node;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class BrowserUtils {
private static final LimeDomListener DOM_ADAPTER = new LimeDomListener();
/**
* Registers a handler for URLs with target = "_blank"
*/
@Inject
public static void registerBlankTarget() {
addTargetedUrlAction("_blank", new UriAction() {
@Override
public boolean uriClicked(final TargetedUri targetedUrl) {
// Open url in new thread to keep Mozilla thread responsive
new ManagedThread(new Runnable() {
public void run() {
NativeLaunchUtils.openURL(targetedUrl.getUri());
}
}).start();
return true;
}
});
}
@Inject
public static void registerMagnetProtocol(final MagnetFactory magnetFactory,
final Provider<MagnetHandler> magnetHandler) {
addProcotolHandlerAction("magnet", new UriAction() {
@Override
public boolean uriClicked(TargetedUri targetedUrl) {
try {
URI uri = URIUtils.toURI(targetedUrl.getUri());
MagnetLink[] magnetLinks = magnetFactory.parseMagnetLink(uri);
for (MagnetLink magnetLink : magnetLinks) {
magnetHandler.get().handleMagnet(magnetLink);
}
} catch (URISyntaxException e) {
return false;
}
return true;
}
});
}
@Inject
public static void registerMailToProtocol(final MagnetFactory magnetFactory) {
addProcotolHandlerAction("mailto", new UriAction() {
@Override
public boolean uriClicked(final TargetedUri targetedUrl) {
// Open url in new thread to keep Mozilla thread responsive
new ManagedThread(new Runnable() {
public void run() {
NativeLaunchUtils.openURL(targetedUrl.getUri());
}
}).start();
return true;
}
});
}
/**
* Adds a {@link UriAction} for the specified target. They are only invoked
* if there is no matching protocol action.
*/
public static void addTargetedUrlAction(String target, UriAction action) {
DOM_ADAPTER.addTargetedUrlAction(target, action);
}
/**
* Adds a {@link UriAction} for the specified URI protocol (magnet, etc..)
*/
public static void addProcotolHandlerAction(String protocol, UriAction action) {
DOM_ADAPTER.addProtocolHandlerAction(protocol, action);
}
/**
*
* @return true if node is a text input, password input or textarea
*/
static boolean isTextControl(Node node) {
boolean isText = false;
if ("input".equalsIgnoreCase(node.getNodeName())) {
Node type = node.getAttributes().getNamedItem("type");
// null, text or password are text controls. Filters out checkbox,
// etc
isText = type == null || "text".equalsIgnoreCase(type.getNodeValue())
|| "password".equalsIgnoreCase(type.getNodeValue());
} else {
isText = "textarea".equalsIgnoreCase(node.getNodeName());
}
return isText;
}
/**
* Adds LimeDomListener to chromeAdapter.
*/
static void addDomListener(final nsIWebBrowserChrome chrome) {
nsIDOMEventTarget eventTarget = XPCOMUtils.qi(chrome.getWebBrowser().getContentDOMWindow(),
nsIDOMWindow2.class).getWindowRoot();
// TODO: some way to listen for javascript?
eventTarget.addEventListener("click", DOM_ADAPTER, true);
eventTarget.addEventListener("submit", DOM_ADAPTER, true);
}
static void removeDomListener(final nsIWebBrowserChrome chrome) {
nsIDOMEventTarget eventTarget = XPCOMUtils.qi(chrome.getWebBrowser().getContentDOMWindow(),
nsIDOMWindow2.class).getWindowRoot();
eventTarget.removeEventListener("click", DOM_ADAPTER, true);
eventTarget.removeEventListener("submit", DOM_ADAPTER, true);
}
}