diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml
index 470c8ada1988..d8889636d101 100644
--- a/platform/platform-resources/src/META-INF/XmlPlugin.xml
+++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml
@@ -71,6 +71,7 @@
+
diff --git a/xml/impl/src/com/intellij/ide/browsers/CustomWebBrowser.java b/xml/impl/src/com/intellij/ide/browsers/CustomWebBrowser.java
new file mode 100644
index 000000000000..d3f296631ae2
--- /dev/null
+++ b/xml/impl/src/com/intellij/ide/browsers/CustomWebBrowser.java
@@ -0,0 +1,46 @@
+package com.intellij.ide.browsers;
+
+import com.intellij.openapi.util.Computable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.UUID;
+
+final class CustomWebBrowser extends WebBrowserBase {
+ private final Computable pathComputable;
+ private final Icon icon;
+ private final String browserNotFoundMessage;
+
+ CustomWebBrowser(@NotNull UUID id,
+ @NotNull BrowserFamily family,
+ @NotNull String name,
+ @NotNull Icon icon,
+ @NotNull Computable pathComputable,
+ @Nullable String browserNotFoundMessage) {
+ super(id, family, name);
+
+ this.pathComputable = pathComputable;
+ this.icon = icon;
+ this.browserNotFoundMessage = browserNotFoundMessage;
+ }
+
+ @Override
+ @NotNull
+ public Icon getIcon() {
+ return icon;
+ }
+
+ @Override
+ @Nullable
+ public String getPath() {
+ return pathComputable.compute();
+ }
+
+ @Override
+ @NotNull
+ public String getBrowserNotFoundMessage() {
+ String message = browserNotFoundMessage;
+ return message == null ? super.getBrowserNotFoundMessage() : message;
+ }
+}
\ No newline at end of file
diff --git a/xml/impl/src/com/intellij/ide/browsers/WebBrowserBase.java b/xml/impl/src/com/intellij/ide/browsers/WebBrowserBase.java
index af7ff95ec08e..fc02f965b6c8 100644
--- a/xml/impl/src/com/intellij/ide/browsers/WebBrowserBase.java
+++ b/xml/impl/src/com/intellij/ide/browsers/WebBrowserBase.java
@@ -16,9 +16,11 @@
package com.intellij.ide.browsers;
import com.intellij.ide.IdeBundle;
+import com.intellij.openapi.util.NullableComputable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import javax.swing.*;
import java.util.UUID;
public abstract class WebBrowserBase extends WebBrowser {
@@ -62,6 +64,16 @@ public abstract class WebBrowserBase extends WebBrowser {
return null;
}
+ @NotNull
+ public static WebBrowser createCustomBrowser(@NotNull BrowserFamily family,
+ @NotNull String name,
+ @NotNull UUID id,
+ @NotNull Icon icon,
+ @NotNull NullableComputable pathComputable,
+ @Nullable String browserNotFoundMessage) {
+ return new CustomWebBrowser(id, family, name, icon, pathComputable, browserNotFoundMessage);
+ }
+
@Override
public String toString() {
return getName() + " (" + getPath() + ")";
diff --git a/xml/impl/src/com/intellij/ide/browsers/WebBrowserManager.java b/xml/impl/src/com/intellij/ide/browsers/WebBrowserManager.java
index 0c7253b95ef1..64cfda4e9882 100644
--- a/xml/impl/src/com/intellij/ide/browsers/WebBrowserManager.java
+++ b/xml/impl/src/com/intellij/ide/browsers/WebBrowserManager.java
@@ -277,15 +277,6 @@ public class WebBrowserManager implements PersistentStateComponent, Mod
((ConfigurableWebBrowser)browser).setActive(isActive);
}
- public void addBrowser(final @NotNull UUID id,
- final @NotNull BrowserFamily family,
- final @NotNull String name,
- final @Nullable String path,
- final boolean active,
- final BrowserSpecificSettings specificSettings) {
- browsers.add(new ConfigurableWebBrowser(id, family, name, path, active, specificSettings));
- }
-
@Nullable
private static UUID parseUuid(@NotNull String id) {
if (id.indexOf('-') == -1) {
@@ -309,9 +300,7 @@ public class WebBrowserManager implements PersistentStateComponent, Mod
UUID id = parseUuid(idOrName);
if (id == null) {
for (ConfigurableWebBrowser browser : browsers) {
- if (browser.getName().equals(idOrName) ||
- browser.getFamily().name().equalsIgnoreCase(idOrName) ||
- browser.getFamily().getName().equalsIgnoreCase(idOrName)) {
+ if (browser.getFamily().name().equalsIgnoreCase(idOrName) || browser.getFamily().getName().equalsIgnoreCase(idOrName)) {
return browser;
}
}
diff --git a/xml/impl/src/com/intellij/ide/browsers/actions/OpenInBrowserActionProducer.java b/xml/impl/src/com/intellij/ide/browsers/actions/OpenInBrowserActionProducer.java
new file mode 100644
index 000000000000..861310e6a6dd
--- /dev/null
+++ b/xml/impl/src/com/intellij/ide/browsers/actions/OpenInBrowserActionProducer.java
@@ -0,0 +1,12 @@
+package com.intellij.ide.browsers.actions;
+
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.extensions.ExtensionPointName;
+
+import java.util.List;
+
+public abstract class OpenInBrowserActionProducer {
+ static final ExtensionPointName EP_NAME = ExtensionPointName.create("org.jetbrains.openInBrowserAction");
+
+ public abstract List getActions();
+}
\ No newline at end of file
diff --git a/xml/impl/src/com/intellij/ide/browsers/actions/OpenInBrowserBaseGroupAction.java b/xml/impl/src/com/intellij/ide/browsers/actions/OpenInBrowserBaseGroupAction.java
index 2d5409fd6974..cf5e9553b110 100644
--- a/xml/impl/src/com/intellij/ide/browsers/actions/OpenInBrowserBaseGroupAction.java
+++ b/xml/impl/src/com/intellij/ide/browsers/actions/OpenInBrowserBaseGroupAction.java
@@ -22,6 +22,8 @@ import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.ComputableActionGroup;
import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,10 +43,15 @@ public abstract class OpenInBrowserBaseGroupAction extends ComputableActionGroup
@Nullable
@Override
public Result compute() {
+ List actionsByEP = new SmartList();
+ for (OpenInBrowserActionProducer actionProducer : OpenInBrowserActionProducer.EP_NAME.getExtensions()) {
+ actionsByEP.addAll(actionProducer.getActions());
+ }
+
List browsers = WebBrowserManager.getInstance().getBrowsers();
boolean addDefaultBrowser = isPopup();
int offset = addDefaultBrowser ? 1 : 0;
- AnAction[] actions = new AnAction[browsers.size() + offset];
+ AnAction[] actions = new AnAction[browsers.size() + offset + actionsByEP.size()];
if (addDefaultBrowser) {
if (myDefaultBrowserAction == null) {
@@ -59,6 +66,8 @@ public abstract class OpenInBrowserBaseGroupAction extends ComputableActionGroup
actions[i + offset] = new BaseWebBrowserAction(browsers.get(i));
}
+ ArrayUtil.copy(actionsByEP, actions, offset + browsers.size());
+
return Result.create(actions, WebBrowserManager.getInstance());
}
};