/* * Copyright (c) 2013, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.github.sdbg.debug.core.configs; import com.github.sdbg.core.DartCore; import com.github.sdbg.debug.core.SDBGDebugCorePlugin; import com.github.sdbg.debug.core.SDBGLaunchConfigWrapper; import com.github.sdbg.debug.core.SDBGLaunchConfigurationDelegate; import com.github.sdbg.debug.core.internal.util.BrowserManager; import com.github.sdbg.debug.core.model.IResourceResolver; import com.github.sdbg.debug.core.util.IBrowserTabChooser; import com.github.sdbg.debug.core.util.IBrowserTabInfo; import com.github.sdbg.utilities.instrumentation.InstrumentationBuilder; import java.io.File; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchManager; //[ { // "title": "New Tab", // "type": "page", // "url": "chrome://newtab/", //}, { // "title": "chrome-extension://becjelbpddbpmopbobpojhgneicbhlgj/_generated_background_page.html", // "type": "other", // "url": "chrome-extension://becjelbpddbpmopbobpojhgneicbhlgj/_generated_background_page.html", //}, { // "title": "Packy", // "type": "other", // "url": "chrome-extension://becjelbpddbpmopbobpojhgneicbhlgj/packy.html", //} ] /** * A ILaunchConfigurationDelegate implementation that can launch Chrome applications. We * conceptually launch the manifest.json file which specifies a Chrome app. We currently send Chrome * the path to the manifest file's parent directory via the --load-extension flag. */ // TODO: This will not work out of the box for GWT SuperDevMode, because GWT SDM is done using a web server and the generated JS file and sourcemaps // do not have a fixed location on the disk - a new directory with these is created on each new SDM recompilation public class ChromeAppLaunchConfigurationDelegate extends SDBGLaunchConfigurationDelegate { private static class ChromeAppBrowserTabChooser implements IBrowserTabChooser { @Override public IBrowserTabInfo chooseTab(List<? extends IBrowserTabInfo> tabs) { for (IBrowserTabInfo tab : tabs) { if (tab.getTitle().startsWith("chrome-extension://")) { continue; } // chrome-extension://kohcodfehgoaolndkcophkcmhjenpfmc/_generated_background_page.html if (tab.getTitle().endsWith("_generated_background_page.html")) { continue; } // chrome-extension://nkeimhogjdpnpccoofpliimaahmaaome/background.html if (tab.getUrl().endsWith("_generated_background_page.html") || tab.getUrl().endsWith("/background.html")) { continue; } if (tab.getUrl().startsWith("chrome-extension://") && tab.getTitle().length() > 0) { return tab; } } return null; } } private static class ChromeAppResourceResolver implements IResourceResolver { private IContainer container; private String prefix; public ChromeAppResourceResolver(IContainer container, IBrowserTabInfo tab) { this.container = container; prefix = tab.getUrl(); int index = prefix.indexOf("//"); if (index != -1) { index = prefix.indexOf('/', index + 2); if (index != -1) { prefix = prefix.substring(0, index + 1); } } } @Override public String getUrlForFile(File file) { IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(file.toURI()); if (files.length > 0) { return getUrlForResource(files[0]); } else { return null; } } @Override public String getUrlForResource(IResource resource) { String relPath = calcRelPath(container, resource); if (relPath != null) { return prefix + relPath; } else { return null; } } @Override public String getUrlRegexForResource(IResource resource) { String relPath = calcRelPath(container, resource); if (relPath != null) { return relPath; } return resource.getFullPath().toString(); } @Override public IResource resolveUrl(String url) { if (url.startsWith(prefix)) { return container.findMember(url.substring(prefix.length())); } else { return null; } } private String calcRelPath(IContainer container, IResource resource) { if (container == null) { return null; } String containerPath = container.getFullPath().toString(); String resourcePath = resource.getFullPath().toString(); if (resourcePath.startsWith(containerPath)) { String relPath = resourcePath.substring(containerPath.length()); if (relPath.startsWith("/")) { return relPath.substring(1); } else { return relPath; } } else { return null; } } } private static BrowserManager browserManager = new BrowserManager("chrome-app") { @Override protected IResourceResolver createResourceResolver(ILaunch launch, ILaunchConfiguration configuration, IBrowserTabInfo tab) { SDBGLaunchConfigWrapper wrapper = new SDBGLaunchConfigWrapper(configuration); return new ChromeAppResourceResolver(wrapper.getApplicationResource().getParent(), tab); } }; public static void dispose() { browserManager.dispose(); } /** * Create a new ChromeAppLaunchConfigurationDelegate. */ public ChromeAppLaunchConfigurationDelegate() { } @Override public void doLaunch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor, InstrumentationBuilder instrumentation) throws CoreException { if (!ILaunchManager.RUN_MODE.equals(mode) && !ILaunchManager.DEBUG_MODE.equals(mode)) { throw new CoreException(SDBGDebugCorePlugin.createErrorStatus("Execution mode '" + mode + "' is not supported.")); } SDBGLaunchConfigWrapper wrapper = new SDBGLaunchConfigWrapper(configuration); IResource jsonResource = wrapper.getApplicationResource(); if (jsonResource == null) { throw new CoreException( SDBGDebugCorePlugin.createErrorStatus("No manifest.json file specified to launch.")); } List<String> extraCommandLineArgs = new ArrayList<String>(); // This is currently only supported on the mac. if (DartCore.isMac()) { extraCommandLineArgs.add("--no-startup-window"); } extraCommandLineArgs.add("--load-and-launch-app=" + jsonResource.getParent().getLocation().toFile().getAbsolutePath()); browserManager.launchBrowser( launch, configuration, null/*resolver*/, new ChromeAppBrowserTabChooser(), null/*url*/, monitor, ILaunchManager.DEBUG_MODE.equals(mode), extraCommandLineArgs); } }