convert BaseOpenInBrowserAction, OpenFileInDefaultBrowserAction, OpenInBrowserRequest, WebBrowserServiceImpl, SelectInDefaultBrowserTarget to kotlin

This commit is contained in:
Vladimir Krivosheev
2016-09-06 14:09:07 +02:00
parent 77026684cc
commit 030f1a5a8c
5 changed files with 321 additions and 431 deletions

View File

@@ -13,208 +13,187 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.browsers.actions;
package com.intellij.ide.browsers.actions
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.browsers.*;
import com.intellij.ide.browsers.impl.WebBrowserServiceImpl;
import com.intellij.internal.statistic.UsageTrigger;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.vcs.vfs.ContentRevisionVirtualFile;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.ui.components.JBList;
import com.intellij.util.BitUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.Url;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xml.util.HtmlUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.concurrency.AsyncPromise;
import org.jetbrains.concurrency.Promise;
import com.intellij.icons.AllIcons
import com.intellij.ide.IdeBundle
import com.intellij.ide.browsers.*
import com.intellij.ide.browsers.impl.WebBrowserServiceImpl
import com.intellij.internal.statistic.UsageTrigger
import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.keymap.KeymapManager
import com.intellij.openapi.keymap.KeymapUtil
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.vcs.vfs.ContentRevisionVirtualFile
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import com.intellij.ui.ColoredListCellRenderer
import com.intellij.ui.components.JBList
import com.intellij.util.BitUtil
import com.intellij.util.Url
import com.intellij.xml.util.HtmlUtil
import org.jetbrains.concurrency.AsyncPromise
import org.jetbrains.concurrency.Promise
import org.jetbrains.concurrency.resolvedPromise
import java.awt.event.InputEvent
import javax.swing.Icon
import javax.swing.JList
import javax.swing.*;
import java.awt.event.InputEvent;
import java.util.Collection;
private val LOG = Logger.getInstance(BaseOpenInBrowserAction::class.java)
public abstract class BaseOpenInBrowserAction extends DumbAwareAction {
private static final Logger LOG = Logger.getInstance(BaseOpenInBrowserAction.class);
protected BaseOpenInBrowserAction(@NotNull WebBrowser browser) {
super(browser.getName(), null, browser.getIcon());
abstract class BaseOpenInBrowserAction : DumbAwareAction {
@Suppress("unused")
protected constructor(browser: WebBrowser) : super(browser.name, null, browser.icon) {
}
@SuppressWarnings("UnusedDeclaration")
protected BaseOpenInBrowserAction(@Nullable String text, @Nullable String description, @Nullable Icon icon) {
super(text, description, icon);
@Suppress("unused")
protected constructor(text: String?, description: String?, icon: Icon?) : super(text, description, icon) {
}
@Nullable
protected abstract WebBrowser getBrowser(@NotNull AnActionEvent event);
@Override
public final void update(AnActionEvent e) {
WebBrowser browser = getBrowser(e);
if (browser == null) {
e.getPresentation().setEnabledAndVisible(false);
return;
companion object {
@JvmStatic
fun doUpdate(event: AnActionEvent): OpenInBrowserRequest? {
val request = createRequest(event.dataContext)
val applicable = request != null && WebBrowserServiceImpl.getProvider(request) != null
event.presentation.isEnabledAndVisible = applicable
return if (applicable) request else null
}
OpenInBrowserRequest result = doUpdate(e);
if (result == null) {
return;
fun open(event: AnActionEvent, browser: WebBrowser?) {
open(createRequest(event.dataContext), BitUtil.isSet(event.modifiers, InputEvent.SHIFT_MASK), browser)
}
String description = getTemplatePresentation().getText();
if (ActionPlaces.CONTEXT_TOOLBAR.equals(e.getPlace())) {
StringBuilder builder = new StringBuilder(description);
builder.append(" (");
Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("WebOpenInAction");
boolean exists = shortcuts.length > 0;
if (exists) {
builder.append(KeymapUtil.getShortcutText(shortcuts[0]));
fun open(request: OpenInBrowserRequest?, preferLocalUrl: Boolean, browser: WebBrowser?) {
if (request == null) {
return
}
if (HtmlUtil.isHtmlFile(result.getFile())) {
builder.append(exists ? ", " : "").append("hold Shift to open URL of local file");
}
builder.append(')');
description = builder.toString();
}
e.getPresentation().setText(description);
}
@Override
public final void actionPerformed(AnActionEvent e) {
WebBrowser browser = getBrowser(e);
if (browser != null) {
UsageTrigger.trigger("OpenInBrowser." + browser.getName());
open(e, browser);
}
}
@Nullable
public static OpenInBrowserRequest createRequest(@NotNull DataContext context) {
final Editor editor = CommonDataKeys.EDITOR.getData(context);
if (editor != null) {
Project project = editor.getProject();
if (project != null && project.isInitialized()) {
PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(context);
if (psiFile == null) {
psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
}
if (psiFile != null && !(psiFile.getVirtualFile() instanceof ContentRevisionVirtualFile)) {
return new OpenInBrowserRequest(psiFile) {
private PsiElement element;
@NotNull
@Override
public PsiElement getElement() {
if (element == null) {
element = getFile().findElementAt(editor.getCaretModel().getOffset());
try {
val urls = WebBrowserService.getInstance().getUrlsToOpen(request, preferLocalUrl)
if (!urls.isEmpty()) {
chooseUrl(urls)
.done { url ->
ApplicationManager.getApplication().saveAll()
BrowserLauncher.getInstance().browse(url.toExternalForm(), browser, request.project)
}
return ObjectUtils.chooseNotNull(element, getFile());
}
};
}
}
catch (e: WebBrowserUrlProvider.BrowserException) {
Messages.showErrorDialog(e.message, IdeBundle.message("browser.error"))
}
catch (e: Exception) {
LOG.error(e)
}
}
}
protected abstract fun getBrowser(event: AnActionEvent): WebBrowser?
override fun update(e: AnActionEvent) {
val browser = getBrowser(e)
if (browser == null) {
e.presentation.isEnabledAndVisible = false
return
}
val result = doUpdate(e) ?: return
var description = templatePresentation.text
if (ActionPlaces.CONTEXT_TOOLBAR == e.place) {
val builder = StringBuilder(description)
builder.append(" (")
val shortcuts = KeymapManager.getInstance().activeKeymap.getShortcuts("WebOpenInAction")
val exists = shortcuts.size > 0
if (exists) {
builder.append(KeymapUtil.getShortcutText(shortcuts[0]))
}
if (HtmlUtil.isHtmlFile(result.file)) {
builder.append(if (exists) ", " else "").append("hold Shift to open URL of local file")
}
builder.append(')')
description = builder.toString()
}
e.presentation.text = description
}
override fun actionPerformed(e: AnActionEvent) {
getBrowser(e)?.let {
UsageTrigger.trigger("OpenInBrowser.${it.name}")
open(e, it)
}
}
}
private fun createRequest(context: DataContext): OpenInBrowserRequest? {
val editor = CommonDataKeys.EDITOR.getData(context)
if (editor != null) {
val project = editor.project
if (project != null && project.isInitialized) {
val psiFile = CommonDataKeys.PSI_FILE.getData(context) ?: PsiDocumentManager.getInstance(project).getPsiFile(editor.document)
if (psiFile != null && psiFile.virtualFile !is ContentRevisionVirtualFile) {
return object : OpenInBrowserRequest() {
override val file: PsiFile = psiFile
private val _element by lazy { file.findElementAt(editor.caretModel.offset) }
override val element: PsiElement
get() = _element ?: file
}
}
}
else {
PsiFile psiFile = CommonDataKeys.PSI_FILE.getData(context);
VirtualFile virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(context);
Project project = CommonDataKeys.PROJECT.getData(context);
if (virtualFile != null && !virtualFile.isDirectory() && virtualFile.isValid() && project != null && project.isInitialized()) {
psiFile = PsiManager.getInstance(project).findFile(virtualFile);
}
if (psiFile != null && !(psiFile.getVirtualFile() instanceof ContentRevisionVirtualFile)) {
return OpenInBrowserRequest.create(psiFile);
}
}
return null;
}
@Nullable
public static OpenInBrowserRequest doUpdate(@NotNull AnActionEvent event) {
OpenInBrowserRequest request = createRequest(event.getDataContext());
boolean applicable = request != null && WebBrowserServiceImpl.getProvider(request) != null;
event.getPresentation().setEnabledAndVisible(applicable);
return applicable ? request : null;
}
public static void open(@NotNull AnActionEvent event, @Nullable WebBrowser browser) {
open(createRequest(event.getDataContext()), BitUtil.isSet(event.getModifiers(), InputEvent.SHIFT_MASK), browser);
}
public static void open(@Nullable final OpenInBrowserRequest request, boolean preferLocalUrl, @Nullable final WebBrowser browser) {
if (request == null) {
return;
else {
var psiFile = CommonDataKeys.PSI_FILE.getData(context)
val virtualFile = CommonDataKeys.VIRTUAL_FILE.getData(context)
val project = CommonDataKeys.PROJECT.getData(context)
if (virtualFile != null && !virtualFile.isDirectory && virtualFile.isValid && project != null && project.isInitialized) {
psiFile = PsiManager.getInstance(project).findFile(virtualFile)
}
try {
Collection<Url> urls = WebBrowserService.getInstance().getUrlsToOpen(request, preferLocalUrl);
if (!urls.isEmpty()) {
chooseUrl(urls)
.done(url -> {
ApplicationManager.getApplication().saveAll();
BrowserLauncher.getInstance().browse(url.toExternalForm(), browser, request.getProject());
});
}
}
catch (WebBrowserUrlProvider.BrowserException e1) {
Messages.showErrorDialog(e1.getMessage(), IdeBundle.message("browser.error"));
}
catch (Exception e1) {
LOG.error(e1);
if (psiFile != null && psiFile.virtualFile !is ContentRevisionVirtualFile) {
return createOpenInBrowserRequest(psiFile)
}
}
return null
}
@NotNull
private static Promise<Url> chooseUrl(@NotNull Collection<Url> urls) {
if (urls.size() == 1) {
return Promise.resolve(ContainerUtil.getFirstItem(urls));
private fun chooseUrl(urls: Collection<Url>): Promise<Url> {
if (urls.size == 1) {
return resolvedPromise(urls.first())
}
val list = JBList<Url>(urls)
list.setCellRenderer(object : ColoredListCellRenderer<Url>() {
override fun customizeCellRenderer(list: JList<out Url>, value: Url?, index: Int, selected: Boolean, hasFocus: Boolean) {
// todo icons looks good, but is it really suitable for all URLs providers?
icon = AllIcons.Nodes.Servlet
append((value as Url).toDecodedForm())
}
})
final JBList list = new JBList(urls);
list.setCellRenderer(new ColoredListCellRenderer() {
@Override
protected void customizeCellRenderer(@NotNull JList list, Object value, int index, boolean selected, boolean hasFocus) {
// todo icons looks good, but is it really suitable for all URLs providers?
setIcon(AllIcons.Nodes.Servlet);
append(((Url)value).toDecodedForm());
}
});
final AsyncPromise<Url> result = new AsyncPromise<>();
JBPopupFactory.getInstance()
val result = AsyncPromise<Url>()
JBPopupFactory.getInstance()
.createListPopupBuilder(list)
.setTitle("Choose Url")
.setItemChoosenCallback(() -> {
Url value = (Url)list.getSelectedValue();
.setItemChoosenCallback {
val value = list.selectedValue
if (value == null) {
result.setError("selected value is null");
result.setError("selected value is null")
}
else {
result.setResult(value);
result.setResult(value)
}
})
.createPopup()
.showInFocusCenter();
return result;
}
}
.createPopup().showInFocusCenter()
return result
}

View File

@@ -13,74 +13,68 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.browsers.actions;
package com.intellij.ide.browsers.actions
import com.intellij.ide.GeneralSettings;
import com.intellij.ide.browsers.*;
import com.intellij.internal.statistic.UsageTrigger;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.xml.util.HtmlUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.intellij.ide.GeneralSettings
import com.intellij.ide.browsers.BrowserLauncherAppless
import com.intellij.ide.browsers.DefaultBrowserPolicy
import com.intellij.ide.browsers.WebBrowser
import com.intellij.ide.browsers.WebBrowserManager
import com.intellij.internal.statistic.UsageTrigger
import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.xml.util.HtmlUtil
public class OpenFileInDefaultBrowserAction extends DumbAwareAction {
@Override
public void update(@NotNull AnActionEvent e) {
Presentation presentation = e.getPresentation();
class OpenFileInDefaultBrowserAction : DumbAwareAction() {
override fun update(e: AnActionEvent) {
val result = BaseOpenInBrowserAction.doUpdate(e) ?: return
OpenInBrowserRequest result = BaseOpenInBrowserAction.doUpdate(e);
if (result == null) {
return;
var description = templatePresentation.description
if (HtmlUtil.isHtmlFile(result.file)) {
description += " (hold Shift to open URL of local file)"
}
String description = getTemplatePresentation().getDescription();
if (HtmlUtil.isHtmlFile(result.getFile())) {
description += " (hold Shift to open URL of local file)";
val presentation = e.presentation
presentation.text = templatePresentation.text
presentation.description = description
findUsingBrowser()?.let {
presentation.icon = it.icon
}
presentation.setText(getTemplatePresentation().getText());
presentation.setDescription(description);
WebBrowser browser = findUsingBrowser();
if (browser != null) {
presentation.setIcon(browser.getIcon());
}
if (ActionPlaces.isPopupPlace(e.getPlace())) {
presentation.setVisible(presentation.isEnabled());
if (ActionPlaces.isPopupPlace(e.place)) {
presentation.isVisible = presentation.isEnabled
}
}
@Nullable
public static WebBrowser findUsingBrowser() {
WebBrowserManager browserManager = WebBrowserManager.getInstance();
DefaultBrowserPolicy defaultBrowserPolicy = browserManager.getDefaultBrowserPolicy();
if (defaultBrowserPolicy == DefaultBrowserPolicy.FIRST || (defaultBrowserPolicy == DefaultBrowserPolicy.SYSTEM && !BrowserLauncherAppless.canUseSystemDefaultBrowserPolicy())) {
return browserManager.getFirstActiveBrowser();
}
else if (defaultBrowserPolicy == DefaultBrowserPolicy.ALTERNATIVE) {
String path = GeneralSettings.getInstance().getBrowserPath();
if (!StringUtil.isEmpty(path)) {
WebBrowser browser = browserManager.findBrowserById(path);
if (browser == null) {
for (WebBrowser item : browserManager.getActiveBrowsers()) {
if (path.equals(item.getPath())) {
return item;
}
override fun actionPerformed(e: AnActionEvent) {
UsageTrigger.trigger("OpenInBrowser.default")
BaseOpenInBrowserAction.open(e, findUsingBrowser())
}
}
fun findUsingBrowser(): WebBrowser? {
val browserManager = WebBrowserManager.getInstance()
val defaultBrowserPolicy = browserManager.defaultBrowserPolicy
if (defaultBrowserPolicy == DefaultBrowserPolicy.FIRST || defaultBrowserPolicy == DefaultBrowserPolicy.SYSTEM && !BrowserLauncherAppless.canUseSystemDefaultBrowserPolicy()) {
return browserManager.firstActiveBrowser
}
else if (defaultBrowserPolicy == DefaultBrowserPolicy.ALTERNATIVE) {
val path = GeneralSettings.getInstance().browserPath
if (!path.isNullOrBlank()) {
val browser = browserManager.findBrowserById(path)
if (browser == null) {
for (item in browserManager.activeBrowsers) {
if (path == item.path) {
return item
}
}
}
else {
return browser
}
}
return null;
}
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
UsageTrigger.trigger("OpenInBrowser.default");
BaseOpenInBrowserAction.open(e, findUsingBrowser());
}
}
return null
}

View File

@@ -13,55 +13,39 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.browsers.actions;
package com.intellij.ide.browsers.actions
import com.intellij.ide.SelectInContext;
import com.intellij.ide.SelectInTargetBase;
import com.intellij.ide.StandardTargetWeights;
import com.intellij.ide.browsers.OpenInBrowserRequest;
import com.intellij.ide.browsers.WebBrowserUrlProvider;
import com.intellij.ide.browsers.impl.WebBrowserServiceImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.impl.http.HttpVirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.xml.XmlBundle;
import com.intellij.xml.util.HtmlUtil;
import com.intellij.ide.SelectInContext
import com.intellij.ide.SelectInTargetBase
import com.intellij.ide.StandardTargetWeights
import com.intellij.ide.browsers.createOpenInBrowserRequest
import com.intellij.ide.browsers.impl.WebBrowserServiceImpl
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.vfs.impl.http.HttpVirtualFile
import com.intellij.psi.PsiElement
import com.intellij.testFramework.LightVirtualFile
import com.intellij.xml.XmlBundle
import com.intellij.xml.util.HtmlUtil
final class SelectInDefaultBrowserTarget extends SelectInTargetBase {
private static final Logger LOG = Logger.getInstance(SelectInDefaultBrowserTarget.class);
private val LOG = Logger.getInstance(SelectInDefaultBrowserTarget::class.java)
@Override
public boolean canSelect(SelectInContext context) {
Object selectorInFile = context.getSelectorInFile();
OpenInBrowserRequest request = selectorInFile instanceof PsiElement ? OpenInBrowserRequest.create((PsiElement)selectorInFile) : null;
if (request == null) {
return false;
}
WebBrowserUrlProvider urlProvider = WebBrowserServiceImpl.getProvider(request);
internal class SelectInDefaultBrowserTarget : SelectInTargetBase() {
override fun canSelect(context: SelectInContext): Boolean {
val selectorInFile = context.selectorInFile as? PsiElement ?: return false
val request = createOpenInBrowserRequest(selectorInFile) ?: return false
val urlProvider = WebBrowserServiceImpl.getProvider(request)
if (urlProvider == null) {
VirtualFile virtualFile = request.getVirtualFile();
return virtualFile instanceof HttpVirtualFile || (HtmlUtil.isHtmlFile(request.getFile()) && !(virtualFile instanceof LightVirtualFile));
val virtualFile = request.virtualFile
return virtualFile is HttpVirtualFile || HtmlUtil.isHtmlFile(request.file) && virtualFile !is LightVirtualFile
}
return true;
return true
}
@Override
public String toString() {
return XmlBundle.message("browser.select.in.default.name");
override fun toString() = XmlBundle.message("browser.select.in.default.name")
override fun selectIn(context: SelectInContext, requestFocus: Boolean) {
BaseOpenInBrowserAction.open(createOpenInBrowserRequest(context.selectorInFile as PsiElement), false, null)
}
@Override
public void selectIn(SelectInContext context, boolean requestFocus) {
PsiElement element = (PsiElement)context.getSelectorInFile();
LOG.assertTrue(element != null);
BaseOpenInBrowserAction.open(OpenInBrowserRequest.create(element), false, null);
}
@Override
public float getWeight() {
return StandardTargetWeights.OS_FILE_MANAGER;
}
override fun getWeight() = StandardTargetWeights.OS_FILE_MANAGER
}

View File

@@ -13,103 +13,89 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.browsers.impl;
package com.intellij.ide.browsers.impl
import com.intellij.ide.browsers.OpenInBrowserRequest;
import com.intellij.ide.browsers.WebBrowserService;
import com.intellij.ide.browsers.WebBrowserUrlProvider;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.Url;
import com.intellij.util.Urls;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xml.util.HtmlUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.intellij.ide.browsers.OpenInBrowserRequest
import com.intellij.ide.browsers.WebBrowserService
import com.intellij.ide.browsers.WebBrowserUrlProvider
import com.intellij.ide.browsers.createOpenInBrowserRequest
import com.intellij.lang.xml.XMLLanguage
import com.intellij.openapi.project.DumbService
import com.intellij.psi.PsiElement
import com.intellij.testFramework.LightVirtualFile
import com.intellij.util.Url
import com.intellij.util.Urls
import com.intellij.util.containers.ContainerUtil
import com.intellij.xml.util.HtmlUtil
import java.util.Collection;
import java.util.Collections;
class WebBrowserServiceImpl : WebBrowserService() {
companion object {
fun getProvider(request: OpenInBrowserRequest): WebBrowserUrlProvider? {
val dumbService = DumbService.getInstance(request.project)
for (urlProvider in WebBrowserUrlProvider.EP_NAME.extensions) {
if ((!dumbService.isDumb || DumbService.isDumbAware(urlProvider)) && urlProvider.canHandleElement(request)) {
return urlProvider
}
}
return null
}
public class WebBrowserServiceImpl extends WebBrowserService {
@NotNull
@Override
public Collection<Url> getUrlsToOpen(@NotNull OpenInBrowserRequest request, boolean preferLocalUrl) throws WebBrowserUrlProvider.BrowserException {
boolean isHtmlOrXml = isHtmlOrXmlFile(request.getFile().getViewProvider().getBaseLanguage());
fun getDebuggableUrls(context: PsiElement?): Collection<Url> {
try {
val request = if (context == null) null else createOpenInBrowserRequest(context)
if (request == null || request.file.viewProvider.baseLanguage === XMLLanguage.INSTANCE) {
return emptyList()
}
else {
// it is client responsibility to set token
request.isAppendAccessToken = false
return getUrls(getProvider(request), request)
}
}
catch (ignored: WebBrowserUrlProvider.BrowserException) {
return emptyList()
}
}
@JvmStatic
fun getDebuggableUrl(context: PsiElement?) = ContainerUtil.getFirstItem(getDebuggableUrls(context))
}
override fun getUrlsToOpen(request: OpenInBrowserRequest, preferLocalUrl: Boolean): Collection<Url> {
val isHtmlOrXml = WebBrowserService.isHtmlOrXmlFile(request.file.viewProvider.baseLanguage)
if (!preferLocalUrl || !isHtmlOrXml) {
DumbService dumbService = DumbService.getInstance(request.getProject());
for (WebBrowserUrlProvider urlProvider : WebBrowserUrlProvider.EP_NAME.getExtensions()) {
if ((!dumbService.isDumb() || DumbService.isDumbAware(urlProvider)) && urlProvider.canHandleElement(request)) {
Collection<Url> urls = getUrls(urlProvider, request);
val dumbService = DumbService.getInstance(request.project)
for (urlProvider in WebBrowserUrlProvider.EP_NAME.extensions) {
if ((!dumbService.isDumb || DumbService.isDumbAware(urlProvider)) && urlProvider.canHandleElement(request)) {
val urls = getUrls(urlProvider, request)
if (!urls.isEmpty()) {
return urls;
return urls
}
}
}
if (!isHtmlOrXml) {
return Collections.emptyList();
return emptyList()
}
}
VirtualFile file = request.getVirtualFile();
return file instanceof LightVirtualFile || !request.getFile().getViewProvider().isPhysical()
? Collections.<Url>emptyList()
: Collections.singletonList(Urls.newFromVirtualFile(file));
}
@NotNull
private static Collection<Url> getUrls(@Nullable WebBrowserUrlProvider provider, @NotNull OpenInBrowserRequest request) throws WebBrowserUrlProvider.BrowserException {
if (provider != null) {
if (request.getResult() != null) {
return request.getResult();
}
try {
return provider.getUrls(request);
}
catch (WebBrowserUrlProvider.BrowserException e) {
if (!HtmlUtil.isHtmlFile(request.getFile())) {
throw e;
}
}
}
return Collections.emptyList();
}
@Nullable
public static WebBrowserUrlProvider getProvider(@NotNull OpenInBrowserRequest request) {
DumbService dumbService = DumbService.getInstance(request.getProject());
for (WebBrowserUrlProvider urlProvider : WebBrowserUrlProvider.EP_NAME.getExtensions()) {
if ((!dumbService.isDumb() || DumbService.isDumbAware(urlProvider)) && urlProvider.canHandleElement(request)) {
return urlProvider;
}
}
return null;
}
@NotNull
public static Collection<Url> getDebuggableUrls(@Nullable PsiElement context) {
try {
OpenInBrowserRequest request = context == null ? null : OpenInBrowserRequest.create(context);
if (request == null || request.getFile().getViewProvider().getBaseLanguage() == XMLLanguage.INSTANCE) {
return Collections.<Url>emptyList();
}
else {
// it is client responsibility to set token
request.setAppendAccessToken(false);
return getUrls(getProvider(request), request);
}
}
catch (WebBrowserUrlProvider.BrowserException ignored) {
return Collections.emptyList();
}
}
@Nullable
public static Url getDebuggableUrl(@Nullable PsiElement context) {
return ContainerUtil.getFirstItem(getDebuggableUrls(context));
val file = if (!request.file.viewProvider.isPhysical) null else request.virtualFile
return if (file is LightVirtualFile || file == null) emptyList() else listOf(Urls.newFromVirtualFile(file))
}
}
private fun getUrls(provider: WebBrowserUrlProvider?, request: OpenInBrowserRequest): Collection<Url> {
if (provider != null) {
request.result?.let { return it }
try {
return provider.getUrls(request)
}
catch (e: WebBrowserUrlProvider.BrowserException) {
if (!HtmlUtil.isHtmlFile(request.file)) {
throw e
}
}
}
return emptyList()
}

View File

@@ -13,88 +13,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.browsers;
package com.intellij.ide.browsers
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.Url;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.util.Url
import java.util.Collection;
abstract class OpenInBrowserRequest() {
var result: Collection<Url>? = null
public abstract class OpenInBrowserRequest {
private Collection<Url> result;
protected PsiFile file;
private boolean appendAccessToken = true;
var isAppendAccessToken = true
public OpenInBrowserRequest(@NotNull PsiFile file) {
this.file = file;
}
val virtualFile: VirtualFile?
get() = file.virtualFile
public OpenInBrowserRequest() {
}
val project: Project
get() = file.project
@Nullable
public static OpenInBrowserRequest create(@NotNull final PsiElement element) {
PsiFile psiFile;
AccessToken token = ReadAction.start();
try {
psiFile = element.isValid() ? element.getContainingFile() : null;
if (psiFile == null || psiFile.getVirtualFile() == null) {
return null;
}
}
finally {
token.finish();
}
abstract val file: PsiFile
abstract val element: PsiElement
}
return new OpenInBrowserRequest(psiFile) {
@NotNull
@Override
public PsiElement getElement() {
return element;
}
};
}
fun createOpenInBrowserRequest(element: PsiElement): OpenInBrowserRequest? {
val psiFile = runReadAction { if (element.isValid) element.containingFile?.let { if (it.virtualFile == null) null else it } else null } ?: return null
return object : OpenInBrowserRequest() {
override val file = psiFile
@NotNull
public PsiFile getFile() {
return file;
}
@NotNull
public VirtualFile getVirtualFile() {
return file.getVirtualFile();
}
@NotNull
public Project getProject() {
return file.getProject();
}
@NotNull
public abstract PsiElement getElement();
public void setResult(@NotNull Collection<Url> result) {
this.result = result;
}
@Nullable
public Collection<Url> getResult() {
return result;
}
public boolean isAppendAccessToken() {
return appendAccessToken;
}
public void setAppendAccessToken(boolean value) {
this.appendAccessToken = value;
override val element = element
}
}