diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 205a162982..e7638e619a 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -4,9 +4,32 @@ This page describes the noteworthy improvements provided by each release of Ecli ### Next release... +## 0.9.0 + +* 📅 Release Date (tentative): May 2020 +* All changes: https://github.com/eclipse/wildwebdeveloper/compare/0.8.3...0.9.0 + +#### Breaking changes + +* Extension point `org.eclipse.wildwebdeveloper.lemminxExtension` now replaces `org.eclipse.wildwebdeveloper.xmllsExtension` +* Interface `LemminxClasspathExtensionProvider` now replaces `XMLLSClasspathExtensionProvider` +* XML Language server is now Eclipse Lemminx 0.11.0. Extensions must be built targetting this language server (package name have changed) + +## 0.8.3 + +* 📅 Release Date: March 19th, 2020 +* All changes: https://github.com/eclipse/wildwebdeveloper/compare/0.8.2...0.8.3 + +#### TypeScript 3.8 support + +Wild Web Developer supports the latest release of TypeScript, 3.8 + +![TypeScript 3.8 demo](documentation-files/typescript38.png) + + ## 0.8.2 -* 📅 Release Date: Mid-March, 2020 +* 📅 Release Date: February 20th, 2020 * All changes: https://github.com/eclipse/wildwebdeveloper/compare/0.8.1...0.8.2 #### NPM Launch shortcut diff --git a/TIPS_and_FAQ.md b/TIPS_and_FAQ.md index e862d1f0db..49facca202 100644 --- a/TIPS_and_FAQ.md +++ b/TIPS_and_FAQ.md @@ -33,6 +33,16 @@ Example `tsconfig.json`: 3. Right click on the entry point of your website (eg. `index.html`) => Debug as => Chrome Debug 4. If a breakpoint is set in your `.ts` source file, it will be hit when the equivalent JavaScript code is run. +#### Debug a client-side code of a web app? + +1. Start your web app's Node.JS web server (usually done through a NPM script in your package.json, eg. `npm start` ). This can be done through the commandline or by right-clicking on a package.json in the Project Explorer => Run as => NPM... +2. Once your web app is running, take note of the local URL it's running on. For React project's, it's by default `http://localhost:3000/` +3. Right click on your project's root directory in the Project Explorer => Debug as => Debug configurations... +4. Create a launch or attach debug configuration for Chrome or Firefox, depending on your preference. +5. For launch debug configurations, select the URL radio button and enter the URL from step 2. For attach debug configurations, simply enter the URL from step 2. +6. Ensure the working directory is correctly set to your project's root folder. +7. Click `apply` followed by `debug` in the bottom right corner of the debug configuration + #### Get instant HTML preview on save ? 1. Open the HTML file with the Generic Editor for edition. diff --git a/documentation-files/typescript38.png b/documentation-files/typescript38.png new file mode 100644 index 0000000000..a8fd591027 Binary files /dev/null and b/documentation-files/typescript38.png differ diff --git a/org.eclipse.wildwebdeveloper.feature/feature.xml b/org.eclipse.wildwebdeveloper.feature/feature.xml index b2d572e033..3dc273d454 100644 --- a/org.eclipse.wildwebdeveloper.feature/feature.xml +++ b/org.eclipse.wildwebdeveloper.feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/org.eclipse.wildwebdeveloper.feature/pom.xml b/org.eclipse.wildwebdeveloper.feature/pom.xml index 2b87512bfc..6d3d7bc3c3 100644 --- a/org.eclipse.wildwebdeveloper.feature/pom.xml +++ b/org.eclipse.wildwebdeveloper.feature/pom.xml @@ -7,7 +7,7 @@ 0.5.0-SNAPSHOT eclipse-feature - 0.8.3-SNAPSHOT + 0.9.0-SNAPSHOT diff --git a/org.eclipse.wildwebdeveloper.tests/META-INF/MANIFEST.MF b/org.eclipse.wildwebdeveloper.tests/META-INF/MANIFEST.MF index 44405c4559..d6907376f1 100644 --- a/org.eclipse.wildwebdeveloper.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.wildwebdeveloper.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Tests for WildWebDeveloper Bundle-SymbolicName: org.eclipse.wildwebdeveloper.tests -Bundle-Version: 0.4.2.qualifier +Bundle-Version: 0.4.3.qualifier Bundle-Vendor: Eclipse Wild Web Developer Automatic-Module-Name: org.eclipse.wildwebdeveloper.tests Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -20,5 +20,6 @@ Require-Bundle: org.eclipse.wildwebdeveloper;bundle-version="0.5.0", org.eclipse.lsp4j;bundle-version="0.9.0", org.eclipse.lsp4j.jsonrpc, org.eclipse.debug.ui, - org.eclipse.core.filesystem + org.eclipse.core.filesystem, + org.eclipse.ui.editors Import-Package: org.eclipse.ui.editors.text diff --git a/org.eclipse.wildwebdeveloper.tests/pom.xml b/org.eclipse.wildwebdeveloper.tests/pom.xml index 848cafd54d..674ab352ad 100644 --- a/org.eclipse.wildwebdeveloper.tests/pom.xml +++ b/org.eclipse.wildwebdeveloper.tests/pom.xml @@ -7,7 +7,7 @@ 0.5.0-SNAPSHOT eclipse-test-plugin - 0.4.2-SNAPSHOT + 0.4.3-SNAPSHOT diff --git a/org.eclipse.wildwebdeveloper.tests/src/org/eclipse/wildwebdeveloper/tests/TestAngular.java b/org.eclipse.wildwebdeveloper.tests/src/org/eclipse/wildwebdeveloper/tests/TestAngular.java index 7b3797de21..159b135678 100644 --- a/org.eclipse.wildwebdeveloper.tests/src/org/eclipse/wildwebdeveloper/tests/TestAngular.java +++ b/org.eclipse.wildwebdeveloper.tests/src/org/eclipse/wildwebdeveloper/tests/TestAngular.java @@ -32,10 +32,12 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.lsp4e.operations.completion.LSContentAssistProcessor; import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.editors.text.TextEditor; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.tests.harness.util.DisplayHelper; -import org.eclipse.ui.texteditor.ITextEditor; import org.junit.Rule; import org.junit.Test; @@ -53,7 +55,7 @@ public void testAngular() throws Exception { IFolder appFolder = project.getFolder("src").getFolder("app"); IFile appComponentFile = appFolder.getFile("app.component.ts"); - ITextEditor editor = (ITextEditor) IDE + TextEditor editor = (TextEditor) IDE .openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), appComponentFile); DisplayHelper.sleep(4000); // Give time for LS to initialize enough before making edit and sending a didChange // make an edit @@ -73,10 +75,11 @@ protected boolean condition() { }.waitForCondition(PlatformUI.getWorkbench().getDisplay(), 50000)); editor.close(false); - editor = (ITextEditor) IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), appFolder.getFile("app.componentWithHtml.ts")); + editor = (TextEditor) IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), appFolder.getFile("app.componentWithHtml.ts")); DisplayHelper.sleep(4000); // Give time for LS to initialize enough before making edit and sending a didChange IFile appComponentHTML = appFolder.getFile("app.componentWithHtml.html"); - editor = (ITextEditor) IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), appComponentHTML); + editor = (TextEditor) IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), appComponentHTML); + document = editor.getDocumentProvider().getDocument(editor.getEditorInput()); assertTrue("No error found on erroneous HTML component file", new DisplayHelper() { @Override protected boolean condition() { IMarker[] markers; @@ -89,6 +92,11 @@ protected boolean condition() { } } }.waitForCondition(editor.getSite().getShell().getDisplay(), 30000)); + // test completion + LSContentAssistProcessor contentAssistProcessor = new LSContentAssistProcessor(); + ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(Utils.getViewer(editor), document.get().indexOf("}}")); + proposals[0].apply(document); + assertEquals("Incorrect completion insertion", "

{{title}}

", document.get()); } public static String getNpmLocation() { diff --git a/org.eclipse.wildwebdeveloper.xml/META-INF/MANIFEST.MF b/org.eclipse.wildwebdeveloper.xml/META-INF/MANIFEST.MF index 4b10ffd75d..4360d432b4 100644 --- a/org.eclipse.wildwebdeveloper.xml/META-INF/MANIFEST.MF +++ b/org.eclipse.wildwebdeveloper.xml/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: XML support using Language Server Bundle-SymbolicName: org.eclipse.wildwebdeveloper.xml;singleton:=true -Bundle-Version: 0.6.1.qualifier +Bundle-Version: 0.7.0.qualifier Bundle-Vendor: Eclipse Wild Web Developer project Automatic-Module-Name: org.eclipse.wildwebdeveloper.xml Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -15,4 +15,4 @@ Require-Bundle: org.eclipse.tm4e.registry;bundle-version="0.3.0", org.eclipse.core.net;bundle-version="1.3.0" Bundle-ActivationPolicy: lazy Bundle-Activator: org.eclipse.wildwebdeveloper.xml.internal.Activator -Export-Package: org.eclipse.wildwebdeveloper.xml;x-friends:="org.eclipse.m2e.xmlls.extension" +Export-Package: org.eclipse.wildwebdeveloper.xml;x-friends:="org.eclipse.m2e.editor.lemminx" diff --git a/org.eclipse.wildwebdeveloper.xml/plugin.xml b/org.eclipse.wildwebdeveloper.xml/plugin.xml index d78f6a6d4b..f40770bba4 100644 --- a/org.eclipse.wildwebdeveloper.xml/plugin.xml +++ b/org.eclipse.wildwebdeveloper.xml/plugin.xml @@ -1,7 +1,7 @@ - + 0.5.0-SNAPSHOT eclipse-plugin - 0.6.1-SNAPSHOT + 0.7.0-SNAPSHOT @@ -24,19 +24,28 @@ - com.googlecode.maven-download-plugin - download-maven-plugin + org.apache.maven.plugins + maven-dependency-plugin + 3.1.2 - fetch-xml + fetch-lemminx generate-resources - wget + copy - https://jcenter.bintray.com/org/lsp4xml/org.eclipse.lsp4xml/0.9.1/org.eclipse.lsp4xml-0.9.1-uber.jar - false + + + org.eclipse.lemminx + org.eclipse.lemminx + 0.11.0 + + uber + + language-servers/server + true @@ -52,4 +61,17 @@
+ + + + lemminx-releases + https://repo.eclipse.org/content/repositories/lemminx-releases/ + + false + + + true + + + diff --git a/org.eclipse.wildwebdeveloper.xml/schema/xmllsExtension.exsd b/org.eclipse.wildwebdeveloper.xml/schema/lemminxExtension.exsd similarity index 88% rename from org.eclipse.wildwebdeveloper.xml/schema/xmllsExtension.exsd rename to org.eclipse.wildwebdeveloper.xml/schema/lemminxExtension.exsd index 80350b366b..fdbb6e1024 100644 --- a/org.eclipse.wildwebdeveloper.xml/schema/xmllsExtension.exsd +++ b/org.eclipse.wildwebdeveloper.xml/schema/lemminxExtension.exsd @@ -3,12 +3,12 @@ - + - This extension point is used to contribute LSP4XML extension jars to extend the functionality of the XML language server. + This extension point is used to contribute Lemminx extension jars to extend the functionality of the XML language server. -Jars can be contributed as an extension resource (by pointing to the path of the jar) or programmatically, by providing an implementation of the <b>XMLLSClasspathExtensionProvider</b> interface. +Jars can be contributed as an extension resource (by pointing to the path of the jar) or programmatically, by providing an implementation of the <b>LemminxClasspathExtensionProvider</b> interface. @@ -73,7 +73,7 @@ Jars can be contributed as an extension resource (by pointing to the path of the - + @@ -85,7 +85,7 @@ Jars can be contributed as an extension resource (by pointing to the path of the - 0.5.0 + 0.7.0 @@ -97,7 +97,7 @@ Jars can be contributed as an extension resource (by pointing to the path of the <br><b><u>Providing a jar as a resource</u></b><br> <br> &lt;extension <br> - <span style="margin-left:2em">point=&quot;org.eclipse.wildwebdeveloper.xml.xmllsExtension&quot;&gt;<br> + <span style="margin-left:2em">point=&quot;org.eclipse.wildwebdeveloper.xml.lemminxExtension&quot;&gt;<br> <span style="margin-left:1em">&lt;jar<br> <span style="margin-left:3em"> path=&quot;/path/to/extension.jar&quot;&gt;<br> <span style="margin-left:1em">&lt;/jar&gt;<br> @@ -108,7 +108,7 @@ Jars can be contributed as an extension resource (by pointing to the path of the <br> &lt;extension <br> <span style="margin-left:2em"> point=&quot;org.eclipse.wildwebdeveloper.xml.xmllsExtension&quot;&gt;<br> <span style="margin-left:1em">&lt;classpathExtensionProvider<br> - <span style="margin-left:3em">provider=&quot;org.eclipse.wildwebdeveloper.xml.XMLLSClasspathExtensionProvider&quot;&gt;<br> + <span style="margin-left:3em">provider=&quot;org.eclipse.m2e.editor.lemminx.MavenLemminxExtensionProvider&quot;&gt;<br> <span style="margin-left:1em">&lt;/classpathExtensionProvider&gt;<br> &lt;/extension&gt; @@ -119,14 +119,14 @@ Jars can be contributed as an extension resource (by pointing to the path of the - <p>The extension jars must implement the <b>IXMLExtension</b> interface and must register with Java Service Provider Interface (SPI) mechanism in the <b>/META-INF/services/org.eclipse.lsp4xml.services.extensions.IXMLExtension</b> file. + <p>The extension jars must implement the <b>IXMLExtension</b> interface and must register with Java Service Provider Interface (SPI) mechanism in the <b>/META-INF/services/org.eclipse.lemminx.services.extensions.IXMLExtension</b> file. </p> <p> See https://github.com/redhat-developer/vscode-xml#custom-xml-extensions for more information. </p> <p> -In order to provide jars to the XML LS programmatically, contributing extensions must implement the <b>XMLLSClasspathExtensionProvider</b> interface. +In order to provide jars to the XML LS programmatically, contributing extensions must implement the <b>LemminxClasspathExtensionProvider</b> interface. </p> diff --git a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/XMLLSClasspathExtensionProvider.java b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/LemminxClasspathExtensionProvider.java similarity index 87% rename from org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/XMLLSClasspathExtensionProvider.java rename to org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/LemminxClasspathExtensionProvider.java index 3d746421c7..0ff9b22783 100644 --- a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/XMLLSClasspathExtensionProvider.java +++ b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/LemminxClasspathExtensionProvider.java @@ -17,9 +17,9 @@ import java.util.function.Supplier; /** - * @since 0.6.0 + * @since 0.7.0 * */ -public interface XMLLSClasspathExtensionProvider extends Supplier> { +public interface LemminxClasspathExtensionProvider extends Supplier> { } diff --git a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/XMLExtensionRegistry.java b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/XMLExtensionRegistry.java index 8f36c10e03..f6c831f27d 100644 --- a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/XMLExtensionRegistry.java +++ b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/XMLExtensionRegistry.java @@ -30,11 +30,11 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; -import org.eclipse.wildwebdeveloper.xml.XMLLSClasspathExtensionProvider; +import org.eclipse.wildwebdeveloper.xml.LemminxClasspathExtensionProvider; public class XMLExtensionRegistry { - private static final String EXTENSION_POINT_ID = Activator.PLUGIN_ID + ".xmllsExtension"; //$NON-NLS-1$ + private static final String EXTENSION_POINT_ID = Activator.PLUGIN_ID + ".lemminxExtension"; //$NON-NLS-1$ private Map extensions = new HashMap<>(); private boolean outOfSync = true; @@ -71,26 +71,26 @@ public List getXMLExtensionJars() { } public List getXMLLSClassPathExtensions() { - Map extensionProviders = getRegisteredClassPathProviders(); + Map extensionProviders = getRegisteredClassPathProviders(); List classpathExtensions = new ArrayList<>(); extensionProviders.entrySet().stream() - .map(Entry::getValue) - .map(XMLLSClasspathExtensionProvider::get) + .map(Entry::getValue) + .map(LemminxClasspathExtensionProvider::get) .forEach(list -> list.forEach(jar -> classpathExtensions.add(jar.getAbsolutePath()))); return classpathExtensions; } - private Map getRegisteredClassPathProviders() { - Map extensionProviders = new HashMap<>(); + private Map getRegisteredClassPathProviders() { + Map extensionProviders = new HashMap<>(); for (IConfigurationElement extension : Platform.getExtensionRegistry() .getConfigurationElementsFor(EXTENSION_POINT_ID)) { try { if (extension.getAttribute("provider") != null) { final Object executableExtension = extension.createExecutableExtension("provider"); - if (executableExtension instanceof XMLLSClasspathExtensionProvider) { - extensionProviders.put(extension, (XMLLSClasspathExtensionProvider) executableExtension); + if (executableExtension instanceof LemminxClasspathExtensionProvider) { + extensionProviders.put(extension, (LemminxClasspathExtensionProvider) executableExtension); } } } catch (Exception ex) { diff --git a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/XMLLanguageServer.java b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/XMLLanguageServer.java index 25c27ba1bd..d50473e94d 100644 --- a/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/XMLLanguageServer.java +++ b/org.eclipse.wildwebdeveloper.xml/src/org/eclipse/wildwebdeveloper/xml/internal/XMLLanguageServer.java @@ -52,13 +52,13 @@ public XMLLanguageServer() { commands.add("-classpath"); try { URL url = FileLocator - .toFileURL(getClass().getResource("/language-servers/server/org.eclipse.lsp4xml-0.9.1-uber.jar")); + .toFileURL(getClass().getResource("/language-servers/server/org.eclipse.lemminx-uber.jar")); List extensionJarPaths = getExtensionJarPaths(); String uberJarPath = new java.io.File(url.getPath()).getAbsolutePath(); jarPaths.add(uberJarPath); jarPaths.addAll(extensionJarPaths); commands.add(String.join(System.getProperty("path.separator"), jarPaths)); - commands.add("org.eclipse.lsp4xml.XMLServerLauncher"); + commands.add("org.eclipse.lemminx.XMLServerLauncher"); setCommands(commands); setWorkingDirectory(System.getProperty("user.dir")); } catch (IOException e) { diff --git a/org.eclipse.wildwebdeveloper/META-INF/MANIFEST.MF b/org.eclipse.wildwebdeveloper/META-INF/MANIFEST.MF index e345431bf3..6d21298ed8 100644 --- a/org.eclipse.wildwebdeveloper/META-INF/MANIFEST.MF +++ b/org.eclipse.wildwebdeveloper/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Wild Web Developer: web development in Eclipse IDE Bundle-SymbolicName: org.eclipse.wildwebdeveloper;singleton:=true Automatic-Module-Name: org.eclipse.wildwebdeveloper -Bundle-Version: 0.5.5.qualifier +Bundle-Version: 0.5.6.qualifier Bundle-Activator: org.eclipse.wildwebdeveloper.Activator Bundle-Vendor: Eclipse Wild Web Developer project Require-Bundle: org.eclipse.ui, @@ -25,7 +25,8 @@ Require-Bundle: org.eclipse.ui, org.eclipse.core.expressions;bundle-version="3.6.0", org.eclipse.tm4e.languageconfiguration, org.eclipse.compare;resolution:=optional, - org.eclipse.ui.console;bundle-version="3.9.0" + org.eclipse.ui.console;bundle-version="3.9.0", + org.eclipse.ui.browser;bundle-version="3.6.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Eclipse-BundleShape: dir diff --git a/org.eclipse.wildwebdeveloper/pom.xml b/org.eclipse.wildwebdeveloper/pom.xml index f6a9dccf03..a2de3676bc 100644 --- a/org.eclipse.wildwebdeveloper/pom.xml +++ b/org.eclipse.wildwebdeveloper/pom.xml @@ -7,7 +7,7 @@ 0.5.0-SNAPSHOT eclipse-plugin - 0.5.5-SNAPSHOT + 0.5.6-SNAPSHOT diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/InitializeLaunchConfigurations.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/InitializeLaunchConfigurations.java index 625cd95bd0..f28383bc31 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/InitializeLaunchConfigurations.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/InitializeLaunchConfigurations.java @@ -17,6 +17,7 @@ package org.eclipse.wildwebdeveloper; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.nio.file.Files; @@ -68,6 +69,14 @@ public static String getNodeJsLocation() { } public static String which(String program) { + + String[] paths = System.getenv("PATH").split(System.getProperty("path.separator")); + for (String path : paths) { + File exe = new File(path, program); + if (exe.canExecute()) + return exe.getAbsolutePath(); + } + String res = null; String[] command = new String[] { "/bin/bash", "-c", "-l", "which " + program}; if (Platform.getOS().equals(Platform.OS_WIN32)) { @@ -82,7 +91,7 @@ public static String which(String program) { } return res; } - + private static String getDefaultNodePath() { switch (Platform.getOS()) { case Platform.OS_MACOSX: diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/AbstractRunHTMLDebugTab.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/AbstractRunHTMLDebugTab.java index a7cde9c912..143f002bd8 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/AbstractRunHTMLDebugTab.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/AbstractRunHTMLDebugTab.java @@ -38,6 +38,7 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.wildwebdeveloper.Activator; +import org.eclipse.wildwebdeveloper.debug.chrome.ChromeRunDAPDebugDelegate; import org.eclipse.wildwebdeveloper.debug.chrome.ChromeRunDebugLaunchShortcut; public abstract class AbstractRunHTMLDebugTab extends AbstractLaunchConfigurationTab { @@ -46,8 +47,12 @@ public abstract class AbstractRunHTMLDebugTab extends AbstractLaunchConfiguratio private Text argumentsText; private Text workingDirectoryText; protected Composite resComposite; - protected AbstractDebugAdapterLaunchShortcut shortcut = new ChromeRunDebugLaunchShortcut(); // contains many - // utilities + private Text urlText; + protected AbstractDebugAdapterLaunchShortcut shortcut = new ChromeRunDebugLaunchShortcut(); + private Button filePath; + private ControlDecoration decoration; + private Button fileRadio; + private Button urlRadio; public AbstractRunHTMLDebugTab() { } @@ -56,38 +61,29 @@ public AbstractRunHTMLDebugTab() { public void createControl(Composite parent) { resComposite = new Composite(parent, SWT.NONE); resComposite.setLayout(new GridLayout(3, false)); - new Label(resComposite, SWT.NONE).setText(Messages.FirefoxDebugTab_File); + + fileRadio = createRadioButton(resComposite, Messages.FirefoxDebugTab_File); + fileRadio.setToolTipText(Messages.AbstractRunHTMLDebugTab_fileRadioToolTip); + fileRadio.setLayoutData(new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); + fileRadio.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> { + urlText.setEnabled(false); + programPathText.setEnabled(true); + filePath.setEnabled(true); + validateProgramPath(); + setDirty(true); + updateLaunchConfigurationDialog(); + })); + this.programPathText = new Text(resComposite, SWT.BORDER); this.programPathText.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); - ControlDecoration decoration = new ControlDecoration(programPathText, SWT.TOP | SWT.LEFT); + decoration = new ControlDecoration(programPathText, SWT.TOP | SWT.LEFT); FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault() .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR); decoration.setImage(fieldDecoration.getImage()); this.programPathText.addModifyListener(event -> { - setDirty(true); - File file = new File(programPathText.getText()); - if (!file.isFile()) { - String errorMessage = Messages.RunProgramTab_error_unknownFile; - setErrorMessage(errorMessage); - decoration.setDescriptionText(errorMessage); - decoration.show(); - } else if (!shortcut.canLaunch(file)) { - String errorMessage = "Not a html file"; //$NON-NLS-1$ - setErrorMessage(errorMessage); - decoration.setDescriptionText(errorMessage); - decoration.show(); - } else if (!file.canRead()) { - String errorMessage = Messages.RunProgramTab_error_nonReadableFile; - setErrorMessage(errorMessage); - decoration.setDescriptionText(errorMessage); - decoration.show(); - } else { - setErrorMessage(null); - decoration.hide(); - } - updateLaunchConfigurationDialog(); + validateProgramPath(); }); - Button filePath = new Button(resComposite, SWT.PUSH); + filePath = new Button(resComposite, SWT.PUSH); filePath.setText(Messages.AbstractRunHTMLDebugTab_browse); filePath.addSelectionListener(SelectionListener.widgetSelectedAdapter((e) -> { FileDialog filePathDialog = new FileDialog(resComposite.getShell()); @@ -100,7 +96,27 @@ public void createControl(Composite parent) { updateLaunchConfigurationDialog(); } })); - + + urlRadio = createRadioButton(resComposite, "URL: "); + urlRadio.setToolTipText(Messages.RunFirefoxDebugTab_URL_Note); + urlRadio.setLayoutData(new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false)); + urlRadio.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> { + programPathText.setEnabled(false); + filePath.setEnabled(false); + urlText.setEnabled(true); + decoration.hide(); + setDirty(true); + updateLaunchConfigurationDialog(); + })); + urlText = new Text(resComposite, SWT.BORDER); + GridData urlTextGD = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + urlTextGD.horizontalSpan = 2; + urlText.setLayoutData(urlTextGD); + urlText.addModifyListener(e -> { + setDirty(true); + updateLaunchConfigurationDialog(); + }); + new Label(resComposite, SWT.NONE).setText(Messages.RunProgramTab_argument); this.argumentsText = new Text(resComposite, SWT.BORDER); GridData argsGD = new GridData(SWT.FILL, SWT.DEFAULT, true, false); @@ -130,10 +146,35 @@ public void createControl(Composite parent) { updateLaunchConfigurationDialog(); } })); - setControl(resComposite); } + private void validateProgramPath() { + setDirty(true); + + File file = new File(programPathText.getText()); + if (!file.isFile()) { + String errorMessage = Messages.RunProgramTab_error_unknownFile; + setErrorMessage(errorMessage); + decoration.setDescriptionText(errorMessage); + decoration.show(); + } else if (!shortcut.canLaunch(file)) { + String errorMessage = "Not a html file"; //$NON-NLS-1$ + setErrorMessage(errorMessage); + decoration.setDescriptionText(errorMessage); + decoration.show(); + } else if (!file.canRead()) { + String errorMessage = Messages.RunProgramTab_error_nonReadableFile; + setErrorMessage(errorMessage); + decoration.setDescriptionText(errorMessage); + decoration.show(); + } else { + setErrorMessage(null); + decoration.hide(); + } + updateLaunchConfigurationDialog(); + } + @Override public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { // Nothing to do @@ -148,6 +189,17 @@ public void initializeFrom(ILaunchConfiguration configuration) { this.argumentsText.setText(configuration.getAttribute(AbstractHTMLDebugDelegate.ARGUMENTS, "")); //$NON-NLS-1$ this.workingDirectoryText.setText( configuration.getAttribute(AbstractHTMLDebugDelegate.CWD, pathOrEmpty(getSelectedProject()))); + this.urlText.setText(configuration.getAttribute(ChromeRunDAPDebugDelegate.URL, "")); //$NON-NLS-1$ + if (urlText.getText().isEmpty()) { + fileRadio.setSelection(true); + urlText.setEnabled(false); + } else { + programPathText.setEnabled(false); + filePath.setEnabled(false); + urlText.setEnabled(true); + urlRadio.setSelection(true); + decoration.hide(); + } } catch (CoreException e) { Activator.getDefault().getLog().log(e.getStatus()); } @@ -156,13 +208,19 @@ public void initializeFrom(ILaunchConfiguration configuration) { @Override public void performApply(ILaunchConfigurationWorkingCopy configuration) { String programPath = this.programPathText.getText(); - configuration.setAttribute(AbstractHTMLDebugDelegate.PROGRAM, programPath); + if (programPathText.isEnabled()) { + configuration.setAttribute(AbstractHTMLDebugDelegate.PROGRAM, programPath); + configuration.setAttribute(ChromeRunDAPDebugDelegate.URL, ""); + } else if (urlText.isEnabled()) { + configuration.setAttribute(ChromeRunDAPDebugDelegate.URL, urlText.getText()); + configuration.setAttribute(ChromeRunDAPDebugDelegate.PROGRAM, ""); + } + configuration.setAttribute(AbstractHTMLDebugDelegate.ARGUMENTS, this.argumentsText.getText()); String workingDirectory = this.workingDirectoryText.getText(); configuration.setAttribute(AbstractHTMLDebugDelegate.CWD, workingDirectory); configuration.setAttribute(DebugPlugin.ATTR_WORKING_DIRECTORY, workingDirectory); configuration.setMappedResources(ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(new File(programPath).toURI())); - } @Override diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/Messages.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/Messages.java index a334a0abb5..35c158c7a9 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/Messages.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/Messages.java @@ -17,10 +17,13 @@ public class Messages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.wildwebdeveloper.debug.messages"; //$NON-NLS-1$ public static String AbstractRunHTMLDebugTab_browse; + public static String AbstractRunHTMLDebugTab_fileRadioToolTip; public static String AttachTab_address; public static String AttachTab_port; public static String AttachTab_title; public static String FirefoxDebugTab_File; + public static String RunFirefoxDebugTab_ReloadOnChange; + public static String RunFirefoxDebugTab_URL_Note; public static String RunProgramTab_argument; public static String RunProgramTab_error_nonReadableFile; public static String RunProgramTab_error_notJSFile; @@ -33,6 +36,9 @@ public class Messages extends NLS { public static String NodeAttach_localRoot; public static String NodeAttach_remoteRoot; public static String NodeAttach_invalidLocalRootDirectory; + public static String ChromeAttachTab_runWith; + public static String ChromeAttachTab_browserTab; + public static String ChromeAttachTab_browserPreferences; static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeAttachDebugDelegate.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeAttachDebugDelegate.java index 1d9fd7a918..abf002bf76 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeAttachDebugDelegate.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeAttachDebugDelegate.java @@ -36,8 +36,9 @@ public void launch(ILaunchConfiguration configuration, String mode, ILaunch laun Map param = new HashMap<>(); param.put(ADDRESS, configuration.getAttribute(ADDRESS, "no address defined")); //$NON-NLS-1$ param.put(AbstractHTMLDebugDelegate.PORT, configuration.getAttribute(NodeAttachDebugDelegate.PORT, 9229)); - param.put("url", "https://www.google.ca/"); - param.put("runtimeExecutable", "/usr/bin/chromium-browser"); + String url = configuration.getAttribute(ChromeRunDAPDebugDelegate.URL, "https://www.google.ca/"); + param.put(ChromeRunDAPDebugDelegate.URL, url); + param.put("runtimeExecutable", ChromeRunDAPDebugDelegate.findChromeLocation(configuration)); super.launchWithParameters(configuration, mode, launch, monitor, param, ChromeRunDAPDebugDelegate.findDebugAdapter()); diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeAttachDebugTabGroup.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeAttachDebugTabGroup.java index 9d535957e2..ed0904ef3b 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeAttachDebugTabGroup.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeAttachDebugTabGroup.java @@ -17,14 +17,14 @@ import org.eclipse.debug.ui.ILaunchConfigurationDialog; import org.eclipse.debug.ui.ILaunchConfigurationTab; import org.eclipse.lsp4e.debug.launcher.DSPOverrideSettingsTab; -import org.eclipse.wildwebdeveloper.debug.node.AttachTab; public class ChromeAttachDebugTabGroup extends AbstractLaunchConfigurationTabGroup { @Override public void createTabs(ILaunchConfigurationDialog dialog, String mode) { setTabs(new ILaunchConfigurationTab[] { - new AttachTab(), + new ChromeAttachTab(), + new ChromeExecutableTab(), new DSPOverrideSettingsTab(), new CommonTab() }); diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeAttachTab.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeAttachTab.java new file mode 100644 index 0000000000..76dcb8ba78 --- /dev/null +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeAttachTab.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2020 Red Hat Inc. and others. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.wildwebdeveloper.debug.chrome; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.wildwebdeveloper.Activator; +import org.eclipse.wildwebdeveloper.debug.Messages; +import org.eclipse.wildwebdeveloper.debug.node.AttachTab; + +public class ChromeAttachTab extends AttachTab { + + private Text urlText; + + public ChromeAttachTab() { + super(9222); + } + + @Override + public void createControl(Composite parent) { + super.createControl(parent); + + new Label(resComposite, SWT.NONE).setText("URL: "); + this.urlText = new Text(resComposite, SWT.BORDER); + this.urlText.setToolTipText(Messages.RunFirefoxDebugTab_URL_Note); + this.urlText.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); + urlText.addModifyListener(e -> { + setDirty(true); + updateLaunchConfigurationDialog(); + }); + } + + @Override + public void initializeFrom(ILaunchConfiguration configuration) { + super.initializeFrom(configuration); + try { + urlText.setText(configuration.getAttribute(ChromeRunDAPDebugDelegate.URL, "")); + } catch (CoreException e) { + Activator.getDefault().getLog().log(e.getStatus()); + } + } + + @Override + public void performApply(ILaunchConfigurationWorkingCopy configuration) { + super.performApply(configuration); + configuration.setAttribute(ChromeRunDAPDebugDelegate.URL, urlText.getText()); + } + +} diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeExecutableTab.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeExecutableTab.java new file mode 100644 index 0000000000..9e9d791568 --- /dev/null +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeExecutableTab.java @@ -0,0 +1,181 @@ +/******************************************************************************* + * Copyright (c) 2020 Red Hat Inc. and others. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.wildwebdeveloper.debug.chrome; + +import java.io.IOException; +import java.io.InputStream; +import java.util.LinkedList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ComboViewer; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.eclipse.ui.dialogs.PreferencesUtil; +import org.eclipse.ui.internal.browser.BrowserManager; +import org.eclipse.ui.internal.browser.IBrowserDescriptor; +import org.eclipse.wildwebdeveloper.Activator; +import org.eclipse.wildwebdeveloper.debug.Messages; + +public class ChromeExecutableTab extends AbstractLaunchConfigurationTab { + + private ComboViewer browserToUse; + private Image image; + private List proposals; + + public ChromeExecutableTab() { + try (InputStream imageResource = getClass().getResourceAsStream("/icons/ChromeIcon.png")) { + image = new Image(Display.getDefault(), imageResource); + } catch (IOException e) { + Activator.getDefault().getLog().error(e.getMessage(), e); + } + } + + @Override + public void createControl(Composite parent) { + Composite res = new Composite(parent, SWT.NONE); + res.setLayout(new GridLayout(2, false)); + + new Label(res, SWT.NONE).setText(Messages.ChromeAttachTab_runWith); + browserToUse = new ComboViewer(res, SWT.VERTICAL | SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); + browserToUse.setContentProvider(new ArrayContentProvider()); + browserToUse.setLabelProvider(new BrowserLabelProvider()); + proposals = new LinkedList<>(); + proposals.add(""); //$NON-NLS-1$ + proposals.addAll(BrowserManager.getInstance().getWebBrowsers().stream().filter(ChromeExecutableTab::isChrome).collect(Collectors.toList())); + browserToUse.setInput(proposals); + browserToUse.addPostSelectionChangedListener(e -> { + setDirty(true); + updateLaunchConfigurationDialog(); + }); + + Link link = new Link(res, SWT.NONE); + link.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false, 2, 1)); + link.setText(Messages.ChromeAttachTab_browserPreferences); + link.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> { + Dialog dialog = PreferencesUtil.createPreferenceDialogOn(link.getShell(), "org.eclipse.ui.browser.preferencePage", null, null); //$NON-NLS-1$ + dialog.open(); + List previous = proposals.stream().filter(IBrowserDescriptor.class::isInstance).map(IBrowserDescriptor.class::cast).collect(Collectors.toList()); + List next = BrowserManager.getInstance().getWebBrowsers(); + List toRemove = new LinkedList<>(previous); + toRemove.removeAll(next); + proposals.removeAll(toRemove); + List toAdd = new LinkedList<>(next); + toAdd.removeAll(previous); + toAdd.removeIf(browser -> !isChrome(browser)); + proposals.addAll(toAdd); + if (!(toAdd.isEmpty() && toRemove.isEmpty())) { + browserToUse.refresh(); + if (browserToUse.getSelection().isEmpty()) { + browserToUse.setSelection(new StructuredSelection("")); //$NON-NLS-1$ + } + } + })); + + setControl(res); + } + + @Override + public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { + configuration.removeAttribute(ChromeRunDAPDebugDelegate.RUNTIME_EXECUTABLE); + } + + + public static boolean isChrome(IBrowserDescriptor desc) { + return desc != null && (desc.getName().toLowerCase().contains("chrom") || (desc.getLocation() != null && desc.getLocation().toLowerCase().contains("chrom"))); + } + + @Override + public void initializeFrom(ILaunchConfiguration configuration) { + try { + String browserLocation = configuration.getAttribute(ChromeRunDAPDebugDelegate.RUNTIME_EXECUTABLE, ""); + if (browserLocation.isEmpty()) { + browserToUse.setSelection(new StructuredSelection(browserLocation)); + } else { + Optional desc = proposals.stream() // + .filter(IBrowserDescriptor.class::isInstance) // + .map(IBrowserDescriptor.class::cast) // + .filter(it -> browserLocation.equals(it.getLocation())) // + .findFirst(); + if (desc.isPresent()) { + desc.ifPresent(it -> browserToUse.setSelection(new StructuredSelection(it))); + } else { + if (!proposals.contains(browserLocation)) { + proposals.add(browserLocation); + } + browserToUse.refresh(); + browserToUse.setSelection(new StructuredSelection(browserLocation)); + } + } + } catch (CoreException ex) { + Activator.getDefault().getLog().log(ex.getStatus()); + } + } + + @Override + public void performApply(ILaunchConfigurationWorkingCopy configuration) { + Object selectedBrowser = ((IStructuredSelection)browserToUse.getSelection()).getFirstElement(); + if (selectedBrowser instanceof IBrowserDescriptor) { + configuration.setAttribute(ChromeRunDAPDebugDelegate.RUNTIME_EXECUTABLE, ((IBrowserDescriptor)selectedBrowser).getLocation()); + } else if (selectedBrowser instanceof String) { + configuration.setAttribute(ChromeRunDAPDebugDelegate.RUNTIME_EXECUTABLE, selectedBrowser); + } + } + + @Override + public String getName() { + return Messages.ChromeAttachTab_browserTab; + } + + @Override + public Image getImage() { + return image; + } + + @Override + public void dispose() { + if (image != null) { + image.dispose(); + } + image = null; + } + + static class BrowserLabelProvider extends LabelProvider { + @Override + public String getText(Object element) { + if (element instanceof IBrowserDescriptor) { + IBrowserDescriptor browser = (IBrowserDescriptor)element; + return browser.getName(); + } + if ("".equals(element)) { + return "[Default]"; + } + return super.getText(element); + } + } + +} diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeRunDAPDebugDelegate.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeRunDAPDebugDelegate.java index ce40eca8f0..ea5a2d19d8 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeRunDAPDebugDelegate.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeRunDAPDebugDelegate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018, 2019 Red Hat Inc. and others. + * Copyright (c) 2020 Red Hat Inc. and others. * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -43,7 +43,8 @@ public class ChromeRunDAPDebugDelegate extends AbstractHTMLDebugDelegate { static final String VERBOSE = "verbose"; private static final String TRACE = "trace"; - private static final String RUNTIME_EXECUTABLE = "runtimeExecutable"; + public static final String RUNTIME_EXECUTABLE = "runtimeExecutable"; + public static final String URL = "url"; private static final String SOURCE_MAPS = "sourceMaps"; @Override @@ -52,9 +53,7 @@ public void launch(ILaunchConfiguration configuration, String mode, ILaunch laun // user settings Map param = new HashMap<>(); - // File to debug - param.put("file", configuration.getAttribute(AbstractHTMLDebugDelegate.PROGRAM, "no program path defined")); //$NON-NLS-1$ - + // Chrome executable arguments String argsString = configuration.getAttribute(AbstractHTMLDebugDelegate.ARGUMENTS, "").trim(); //$NON-NLS-1$ if (!argsString.isEmpty()) { @@ -74,6 +73,14 @@ public void launch(ILaunchConfiguration configuration, String mode, ILaunch laun param.put(AbstractHTMLDebugDelegate.ENV, envJson); } + // File or URL to debug + String url = configuration.getAttribute(URL, ""); + if (!url.equals("")) { + param.put(URL, url); + } else { + param.put("file", configuration.getAttribute(AbstractHTMLDebugDelegate.PROGRAM, "no program path defined")); //$NON-NLS-1$ + } + // Chrome working directory String cwd = configuration.getAttribute(AbstractHTMLDebugDelegate.CWD, "").trim(); //$NON-NLS-1$ if (!cwd.isEmpty()) { @@ -83,7 +90,7 @@ public void launch(ILaunchConfiguration configuration, String mode, ILaunch laun param.put(SOURCE_MAPS, true); // TODO: Let user point to the location of their Chrome executable - param.put(RUNTIME_EXECUTABLE, findChromeLocation()); + param.put(RUNTIME_EXECUTABLE, findChromeLocation(configuration)); if (configuration.getAttribute(VERBOSE, false)) { param.put(TRACE, VERBOSE); @@ -104,18 +111,36 @@ static File findDebugAdapter() { Display.getDefault().asyncExec(() -> ErrorDialog.openError(Display.getDefault().getActiveShell(), "Debug error", e.getMessage(), errorStatus)); //$NON-NLS-1$ } return null; - } - private String findChromeLocation() { - String res = InitializeLaunchConfigurations.which("chromium-browser"); - if (res == null) { - res = InitializeLaunchConfigurations.which("google-chrome-stable"); + static String findChromeLocation(ILaunchConfiguration configuration) { + String res = "chromium-browser"; //$NON-NLS-1$ + try { + res = configuration.getAttribute(RUNTIME_EXECUTABLE, "chromium-browser"); //$NON-NLS-1$ + } catch (CoreException e) { + IStatus errorStatus = new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); + Activator.getDefault().getLog().log(errorStatus); + } + if (new File(res).isAbsolute()) { + return res; + } + if (res == null || res.isEmpty()) { + res = "chromium-browser"; //$NON-NLS-1$ + } + // Failsafe, in case user doesn't have their preferred browser + res = InitializeLaunchConfigurations.which(res); + if (res != null) { + return res; + } + res = InitializeLaunchConfigurations.which("chromium-browser"); + if (res != null) { + return res; } - if (res == null) { - res = "path/to/chrome"; + res = InitializeLaunchConfigurations.which("google-chrome-stable"); + if (res != null) { + return res; } - return res; + return "path/to/chrome"; } } diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeRunDebugLaunchShortcut.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeRunDebugLaunchShortcut.java index 04f60a7b75..375fc1b697 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeRunDebugLaunchShortcut.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeRunDebugLaunchShortcut.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Red Hat Inc. and others. + * Copyright (c) 2020 Red Hat Inc. and others. * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -19,4 +19,5 @@ public class ChromeRunDebugLaunchShortcut extends AbstractHTMLDebugAdapterLaunch public ChromeRunDebugLaunchShortcut() { super(ChromeRunDAPDebugDelegate.ID); } + } diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeRunDebugTabGroup.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeRunDebugTabGroup.java index d885429d89..156e04a030 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeRunDebugTabGroup.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/ChromeRunDebugTabGroup.java @@ -26,6 +26,7 @@ public void createTabs(ILaunchConfigurationDialog dialog, String mode) { setTabs(new ILaunchConfigurationTab[] { new RunChromeDebugTab(), new EnvironmentTab(), + new ChromeExecutableTab(), new DSPOverrideSettingsTab(), new CommonTab() }); diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/RunChromeDebugTab.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/RunChromeDebugTab.java index 2c04e492a0..e749fd12e0 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/RunChromeDebugTab.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/chrome/RunChromeDebugTab.java @@ -30,7 +30,7 @@ public RunChromeDebugTab() { public void createControl(Composite parent) { super.createControl(parent); verboseConsoleOutput = new Button(resComposite, SWT.CHECK); - verboseConsoleOutput.setText("Verbose console output"); + verboseConsoleOutput.setText("Verbose output"); verboseConsoleOutput.addSelectionListener(SelectionListener.widgetSelectedAdapter((e) -> { setDirty(true); updateLaunchConfigurationDialog(); diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/firefox/FirefoxAttachTab.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/firefox/FirefoxAttachTab.java index 814c9e92eb..44785149df 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/firefox/FirefoxAttachTab.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/firefox/FirefoxAttachTab.java @@ -26,6 +26,10 @@ class FirefoxAttachTab extends AttachTab { + public FirefoxAttachTab() { + super(6000); + } + @Override public void createControl(Composite parent) { super.createControl(parent); diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/firefox/FirefoxRunDABDebugDelegate.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/firefox/FirefoxRunDABDebugDelegate.java index ab12a29700..6292fe9db9 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/firefox/FirefoxRunDABDebugDelegate.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/firefox/FirefoxRunDABDebugDelegate.java @@ -32,6 +32,7 @@ import org.eclipse.wildwebdeveloper.Activator; import org.eclipse.wildwebdeveloper.InitializeLaunchConfigurations; import org.eclipse.wildwebdeveloper.debug.AbstractHTMLDebugDelegate; +import org.eclipse.wildwebdeveloper.debug.chrome.ChromeRunDAPDebugDelegate; public class FirefoxRunDABDebugDelegate extends AbstractHTMLDebugDelegate { @@ -58,7 +59,16 @@ public void launch(ILaunchConfiguration configuration, String mode, ILaunch laun param.put(REQUEST, "launch"); //$NON-NLS-1$ // TODO: Let user set location of firefox executable param.put(FIREFOX_EXECUTABLE, findFirefoxLocation()); - param.put(FILE, configuration.getAttribute(AbstractHTMLDebugDelegate.PROGRAM, "No program path set").trim()); //$NON-NLS-1$ + + // File or URL to debug + String url = configuration.getAttribute(ChromeRunDAPDebugDelegate.URL, ""); + if (!url.isEmpty()) { + param.put(ChromeRunDAPDebugDelegate.URL, url); + File projectDirectory = new File(configuration.getAttribute(AbstractHTMLDebugDelegate.CWD, "")); + param.put("webRoot", projectDirectory.getAbsolutePath()); + } else { + param.put(FILE, configuration.getAttribute(AbstractHTMLDebugDelegate.PROGRAM, "No program path set").trim()); //$NON-NLS-1$ + } param.put(PREFERENCES, "{}"); //$NON-NLS-1$ param.put(TMP_DIRS, System.getProperty("java.io.tmpdir")); //$NON-NLS-1$ param.put(TYPE, "firefox"); //$NON-NLS-1$ diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/firefox/RunFirefoxDebugTab.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/firefox/RunFirefoxDebugTab.java index f55d436084..5a508098c7 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/firefox/RunFirefoxDebugTab.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/firefox/RunFirefoxDebugTab.java @@ -18,6 +18,7 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.wildwebdeveloper.debug.AbstractRunHTMLDebugTab; +import org.eclipse.wildwebdeveloper.debug.Messages; public class RunFirefoxDebugTab extends AbstractRunHTMLDebugTab { private Button reloadOnChange; @@ -30,12 +31,11 @@ public RunFirefoxDebugTab() { public void createControl(Composite parent) { super.createControl(parent); reloadOnChange = new Button(resComposite, SWT.CHECK); - reloadOnChange.setText("Reload on change"); + reloadOnChange.setText(Messages.RunFirefoxDebugTab_ReloadOnChange); reloadOnChange.addSelectionListener(SelectionListener.widgetSelectedAdapter((e) -> { setDirty(true); updateLaunchConfigurationDialog(); })); - } @Override diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/messages.properties b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/messages.properties index ec7ed94d0f..cb1d4169e9 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/messages.properties +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/messages.properties @@ -11,10 +11,13 @@ # Mickael Istria (Red Hat Inc.) - initial implementation ################################################################ AbstractRunHTMLDebugTab_browse=\ud83d\udcc2 Browse... +AbstractRunHTMLDebugTab_fileRadioToolTip=The local .html file to debug. AttachTab_address=Address: AttachTab_port=Port: AttachTab_title=\ud83d\udd17 Attach FirefoxDebugTab_File=File +RunFirefoxDebugTab_ReloadOnChange=Reload on change +RunFirefoxDebugTab_URL_Note=The URL where the web application is being hosted on (eg. http://localhost:3000)\nUse for debuging client-side code of a web application. RunProgramTab_argument=Arguments RunProgramTab_error_nonReadableFile=Not allowed to read file. RunProgramTab_error_notJSFile=File is not a JS file. @@ -28,4 +31,7 @@ and if you're debugging a non-local instance, have "devtools.debugger.remote-ena NodeAttach_rootMapDescription=\ud83d\udd17 Map roots (when debugging on a different filesystem) NodeAttach_localRoot=\ud83d\udcbb Local root path: NodeAttach_remoteRoot=\u2601\uFE0F Remote root path: -NodeAttach_invalidLocalRootDirectory=Invalid local root directory \ No newline at end of file +NodeAttach_invalidLocalRootDirectory=Invalid local root directory +ChromeAttachTab_runWith=Run with: +ChromeAttachTab_browserTab=Browser +ChromeAttachTab_browserPreferences=Check Web Browser preferences to add or remove browsers from those proposals. \ No newline at end of file diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/node/AttachTab.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/node/AttachTab.java index 873541f9e6..78d69aacfe 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/node/AttachTab.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/node/AttachTab.java @@ -30,10 +30,16 @@ public class AttachTab extends AbstractLaunchConfigurationTab { private Text addressText; private Spinner portSpinner; + private int defaultPort; + protected Composite resComposite; + + public AttachTab(int defaultPort) { + this.defaultPort = defaultPort; + } @Override public void createControl(Composite parent) { - Composite resComposite = new Composite(parent, SWT.NONE); + resComposite = new Composite(parent, SWT.NONE); resComposite.setLayout(new GridLayout(2, false)); resComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); new Label(resComposite, SWT.NONE).setText(Messages.AttachTab_address); @@ -57,14 +63,14 @@ public void createControl(Composite parent) { @Override public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(NodeAttachDebugDelegate.ADDRESS, "localhost"); - configuration.setAttribute(NodeAttachDebugDelegate.PORT, 9229); + configuration.setAttribute(NodeAttachDebugDelegate.PORT, defaultPort); } @Override public void initializeFrom(ILaunchConfiguration configuration) { try { this.addressText.setText(configuration.getAttribute(NodeAttachDebugDelegate.ADDRESS, "")); //$NON-NLS-1$ - this.portSpinner.setSelection(configuration.getAttribute(NodeAttachDebugDelegate.PORT, -1)); + this.portSpinner.setSelection(defaultPort); } catch (CoreException e) { Activator.getDefault().getLog().log(e.getStatus()); } diff --git a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/node/NodeAttachDebugTab.java b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/node/NodeAttachDebugTab.java index 0c4dea6b95..aba5f0839c 100644 --- a/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/node/NodeAttachDebugTab.java +++ b/org.eclipse.wildwebdeveloper/src/org/eclipse/wildwebdeveloper/debug/node/NodeAttachDebugTab.java @@ -37,6 +37,10 @@ import com.google.gson.Gson; public class NodeAttachDebugTab extends AttachTab { + public NodeAttachDebugTab() { + super(9229); + } + private Text localRootText; private Text remoteRootText;