--- a/php.project/manifest.mf +++ a/php.project/manifest.mf @@ -1,6 +1,6 @@ Manifest-Version: 1.0 AutoUpdate-Show-In-Client: false -OpenIDE-Module-Specification-Version: 2.61 +OpenIDE-Module-Specification-Version: 2.62 OpenIDE-Module: org.netbeans.modules.php.project OpenIDE-Module-Layer: org/netbeans/modules/php/project/resources/layer.xml OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/php/project/resources/Bundle.properties --- a/php.project/nbproject/project.xml +++ a/php.project/nbproject/project.xml @@ -315,6 +315,14 @@ + org.netbeans.modules.web.browser.api + + + + 1.5 + + + org.netbeans.modules.web.common --- a/php.project/src/org/netbeans/modules/php/project/PhpProject.java +++ a/php.project/src/org/netbeans/modules/php/project/PhpProject.java @@ -48,6 +48,8 @@ import java.beans.PropertyChangeSupport; import java.io.File; import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -84,6 +86,7 @@ import org.netbeans.modules.php.project.copysupport.CopySupport; import org.netbeans.modules.php.project.internalserver.InternalWebServer; import org.netbeans.modules.php.project.problems.ProjectPropertiesProblemProvider; +import org.netbeans.modules.php.project.ui.actions.support.CommandUtils; import org.netbeans.modules.php.project.ui.actions.support.ConfigAction; import org.netbeans.modules.php.project.ui.codecoverage.PhpCoverageProvider; import org.netbeans.modules.php.project.ui.customizer.CustomizerProviderImpl; @@ -94,6 +97,7 @@ import org.netbeans.modules.php.spi.framework.PhpFrameworkProvider; import org.netbeans.modules.php.spi.framework.PhpModuleIgnoredFilesExtender; import org.netbeans.modules.web.common.spi.ProjectWebRootProvider; +import org.netbeans.modules.web.common.spi.ServerURLMappingImplementation; import org.netbeans.spi.project.AuxiliaryConfiguration; import org.netbeans.spi.project.support.ant.AntBasedProjectRegistration; import org.netbeans.spi.project.support.ant.AntProjectEvent; @@ -606,7 +610,8 @@ InternalWebServer.createForProject(this), ProjectPropertiesProblemProvider.createForProject(this), UILookupMergerSupport.createProjectProblemsProviderMerger(), - new ProjectWebRootProviderImpl() + new ProjectWebRootProviderImpl(), + ServerMapping.create(this), // ?? getRefHelper() }); } @@ -1015,4 +1020,88 @@ return Collections.unmodifiableList(list); } } -} + + private static final class ServerMapping implements ServerURLMappingImplementation, PropertyChangeListener { + + private final PhpProject project; + + private volatile String projectRootUrl; + + + private ServerMapping(PhpProject project) { + assert project != null; + this.project = project; + } + + public static ServerMapping create(PhpProject project) { + ServerMapping serverMapping = new ServerMapping(project); + ProjectPropertiesSupport.addWeakPropertyEvaluatorListener(project, serverMapping); + return serverMapping; + } + + @Override + public URL toServer(int projectContext, FileObject projectFile) { + init(); + if (projectRootUrl == null) { + return null; + } + FileObject webRoot = project.getWebRootDirectory(); + if (webRoot == null) { + return null; + } + String relPath = FileUtil.getRelativePath(webRoot, projectFile); + if (relPath == null) { + return null; + } + try { + return new URL(projectRootUrl + relPath); + } catch (MalformedURLException ex) { + return null; + } + } + + @Override + public FileObject fromServer(int projectContext, URL serverURL) { + init(); + if (projectRootUrl == null) { + return null; + } + FileObject webRoot = project.getWebRootDirectory(); + if (webRoot == null) { + return null; + } + String url = CommandUtils.urlToString(serverURL, true); + if (url.startsWith(projectRootUrl)) { + return webRoot.getFileObject(url.substring(projectRootUrl.length())); + } + return null; + } + + private void init() { + if (projectRootUrl == null) { + projectRootUrl = getProjectRootUrl(); + } + } + + private String getProjectRootUrl() { + try { + String url = CommandUtils.urlToString(CommandUtils.getBaseURL(project, true), true); + if (!url.endsWith("/")) { // NOI18N + url += "/"; // NOI18N + } + return url; + } catch (MalformedURLException ex) { + return null; + } + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (PhpProjectProperties.URL.equals(evt.getPropertyName())) { + projectRootUrl = null; + } + } + + } + +} --- a/php.project/src/org/netbeans/modules/php/project/ui/actions/support/CommandUtils.java +++ a/php.project/src/org/netbeans/modules/php/project/ui/actions/support/CommandUtils.java @@ -43,6 +43,8 @@ import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLEncoder; import java.util.ArrayList; @@ -51,6 +53,8 @@ import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import org.netbeans.modules.php.project.deprecated.PhpProgram.InvalidPhpProgramException; import org.netbeans.modules.php.api.util.FileUtils; import org.netbeans.modules.php.api.util.StringUtils; @@ -80,6 +84,9 @@ * @author Radek Matous, Tomas Mysik */ public final class CommandUtils { + + private static final Logger LOGGER = Logger.getLogger(CommandUtils.class.getName()); + private static final String HTML_MIME_TYPE = "text/html"; // NOI18N private CommandUtils() { @@ -469,6 +476,41 @@ return new URL(baseURLPath); } + public static String urlToString(URL url, boolean pathOnly) { + URI uri; + try { + uri = url.toURI(); + } catch (URISyntaxException ex) { + // fallback: + LOGGER.log(Level.FINE, "URL '{0}' cannot be converted to URI.", url); + String res = url.toExternalForm(); + int end = res.lastIndexOf('?'); // NOI18N + if (end == -1) { + end = res.lastIndexOf('#'); // NOI18N + } + if (pathOnly && end != -1) { + res = res.substring(0, end); + } + return res; + } + StringBuilder sb = new StringBuilder(100); + sb.append(uri.getScheme()); + sb.append("://"); // NOI18N + if (uri.getAuthority() != null) { + sb.append(uri.getAuthority()); + } + sb.append(uri.getPath()); + if (!pathOnly && uri.getQuery() != null) { + sb.append("?"); // NOI18N + sb.append(uri.getQuery()); + } + if (!pathOnly && uri.getFragment() != null) { + sb.append("#"); // NOI18N + sb.append(uri.getFragment()); + } + return sb.toString(); + } + /** * Get {@link Command} for given project and command name (identifier). * @param project project to get a command for. --- a/php.project/src/org/netbeans/modules/php/project/ui/actions/support/ConfigActionLocal.java +++ a/php.project/src/org/netbeans/modules/php/project/ui/actions/support/ConfigActionLocal.java @@ -43,7 +43,6 @@ package org.netbeans.modules.php.project.ui.actions.support; import java.net.MalformedURLException; -import java.net.URISyntaxException; import java.net.URL; import java.util.concurrent.Callable; import java.util.concurrent.Executors; @@ -54,6 +53,7 @@ import org.netbeans.modules.php.project.spi.XDebugStarter; import org.netbeans.modules.php.project.ui.customizer.PhpProjectProperties.DebugUrl; import org.netbeans.modules.php.project.ui.customizer.PhpProjectProperties.XDebugUrlArguments; +import org.netbeans.modules.web.browser.api.BrowserSupport; import org.openide.awt.HtmlBrowser; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; @@ -108,7 +108,7 @@ @Override public void runProject() { try { - HtmlBrowser.URLDisplayer.getDefault().showURL(CommandUtils.urlForProject(project)); + showProjectUrl(CommandUtils.urlForProject(project)); } catch (MalformedURLException ex) { Exceptions.printStackTrace(ex); } @@ -133,7 +133,7 @@ @Override public void run() { if (urlToShow[0] != null) { - HtmlBrowser.URLDisplayer.getDefault().showURL(urlToShow[0]); + showProjectUrl(urlToShow[0]); } } }; @@ -142,7 +142,7 @@ @Override public boolean cancel() { if (urlToShow[1] != null) { - HtmlBrowser.URLDisplayer.getDefault().showURL(urlToShow[1]); + showProjectUrl(urlToShow[1]); } return true; } @@ -172,7 +172,7 @@ preShowUrl(context); - HtmlBrowser.URLDisplayer.getDefault().showURL(url); + showContextUrl(url, context); } catch (MalformedURLException ex) { //TODO: improve error handling Exceptions.printStackTrace(ex); @@ -234,7 +234,7 @@ @Override public void run() { if (urlForStartDebugging != null) { - HtmlBrowser.URLDisplayer.getDefault().showURL(urlForStartDebugging); + showFileUrl(urlForStartDebugging, selectedFile); } } }; @@ -243,7 +243,7 @@ @Override public boolean cancel() { if (urlForStopDebugging != null) { - HtmlBrowser.URLDisplayer.getDefault().showURL(urlForStopDebugging); + showFileUrl(urlForStopDebugging, selectedFile); } return true; } @@ -279,6 +279,34 @@ dbgStarter.start(project, initDebuggingCallable, props); } + void showProjectUrl(URL url) { + showFileUrl(url, CommandUtils.fileForProject(project, webRoot)); + } + + private void showContextUrl(URL url, Lookup context) { + FileObject file = CommandUtils.fileForContextOrSelectedNodes(context); + if (file != null) { + showFileUrl(url, file); + } else { + assert false : "FO should be found for context"; // NOI18N + showProjectUrl(url); + } + } + + void showFileUrl(URL url, FileObject file) { + if (isEaselEnabled()) { + // easel + BrowserSupport.getDefault().load(url, file); + } else { + // use standard browser + HtmlBrowser.URLDisplayer.getDefault().showURL(url); + } + } + + private static boolean isEaselEnabled() { + return Boolean.getBoolean("easel.everywhere"); // NOI18N + } + private static final class StopDebuggingException extends Exception { private static final long serialVersionUID = -22807171434417714L; } --- a/web.browser.api/manifest.mf +++ a/web.browser.api/manifest.mf @@ -3,5 +3,5 @@ OpenIDE-Module-Layer: org/netbeans/modules/web/browser/ui/resources/layer.xml OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/web/browser/api/Bundle.properties OpenIDE-Module-Requires: org.openide.windows.WindowManager -OpenIDE-Module-Specification-Version: 1.4 +OpenIDE-Module-Specification-Version: 1.5 --- a/web.browser.api/nbproject/project.xml +++ a/web.browser.api/nbproject/project.xml @@ -129,6 +129,7 @@ org.netbeans.modules.html org.netbeans.modules.html.navigator org.netbeans.modules.javascript.jstestdriver + org.netbeans.modules.php.project org.netbeans.modules.web.clientproject org.netbeans.modules.web.clientproject.api org.netbeans.modules.web.inspect