Mobile Browsers for Web and PHP projects browser_toolbar_selector
authorJan Becicka <jbecicka@netbeans.org>
Tue, 26 Mar 2013 14:42:53 +0100
branchbrowser_toolbar_selector
changeset 257032669d1c4170b5
parent 257031 3366f84c882f
child 257049 b08021aee1ce
Mobile Browsers for Web and PHP projects
cordova.platforms.android/src/org/netbeans/modules/cordova/platforms/android/AndroidBrowser.java
cordova.platforms.android/src/org/netbeans/modules/cordova/platforms/android/EnhancedBrowserImpl.java
cordova.platforms.android/src/org/netbeans/modules/cordova/platforms/android/EnhancedBrowserProviderImpl.java
cordova.platforms.ios/src/org/netbeans/modules/cordova/platforms/ios/EnhancedBrowserImpl.java
cordova.platforms.ios/src/org/netbeans/modules/cordova/platforms/ios/EnhancedBrowserProviderImpl.java
cordova.platforms.ios/src/org/netbeans/modules/cordova/platforms/ios/IOSBrowser.java
cordova.platforms/src/org/netbeans/modules/cordova/platforms/BuildPerformer.java
cordova/src/org/netbeans/modules/cordova/CordovaPerformer.java
     1.1 --- a/cordova.platforms.android/src/org/netbeans/modules/cordova/platforms/android/AndroidBrowser.java	Tue Mar 26 10:19:48 2013 +0100
     1.2 +++ b/cordova.platforms.android/src/org/netbeans/modules/cordova/platforms/android/AndroidBrowser.java	Tue Mar 26 14:42:53 2013 +0100
     1.3 @@ -43,17 +43,67 @@
     1.4  
     1.5  import java.awt.Component;
     1.6  import java.beans.PropertyChangeListener;
     1.7 +import java.io.IOException;
     1.8  import java.net.URL;
     1.9 +import java.util.concurrent.atomic.AtomicBoolean;
    1.10 +import java.util.logging.Level;
    1.11 +import java.util.logging.Logger;
    1.12 +import javax.swing.JOptionPane;
    1.13 +import javax.swing.SwingUtilities;
    1.14 +import org.netbeans.api.options.OptionsDisplayer;
    1.15 +import org.netbeans.api.progress.ProgressUtils;
    1.16 +import org.netbeans.api.project.Project;
    1.17 +import org.netbeans.modules.cordova.platforms.BuildPerformer;
    1.18  import org.netbeans.modules.cordova.platforms.Device;
    1.19 +import org.netbeans.modules.cordova.platforms.PlatformManager;
    1.20 +import org.netbeans.modules.web.browser.spi.EnhancedBrowser;
    1.21 +import static org.netbeans.spi.project.ActionProvider.COMMAND_RUN;
    1.22 +import static org.netbeans.spi.project.ActionProvider.COMMAND_RUN_SINGLE;
    1.23 +import org.openide.DialogDisplayer;
    1.24 +import org.openide.NotifyDescriptor;
    1.25  import org.openide.awt.HtmlBrowser;
    1.26 +import org.openide.util.Exceptions;
    1.27 +import org.openide.util.Lookup;
    1.28 +import org.openide.util.lookup.Lookups;
    1.29 +import org.openide.windows.WindowManager;
    1.30  
    1.31  /**
    1.32   *
    1.33   * @author Jan Becicka
    1.34   */
    1.35 -public class AndroidBrowser extends HtmlBrowser.Impl {
    1.36 +public class AndroidBrowser extends HtmlBrowser.Impl implements EnhancedBrowser{
    1.37      private final Kind kind;
    1.38      
    1.39 +    private static final Logger LOGGER = Logger.getLogger(EnhancedBrowserImpl.class.getName());
    1.40 +    
    1.41 +    private Lookup context;
    1.42 +
    1.43 +    @Override
    1.44 +    public boolean hasEnhancedMode() {
    1.45 +        return false;
    1.46 +    }
    1.47 +
    1.48 +    @Override
    1.49 +    public void setEnhancedMode(boolean mode) {
    1.50 +    }
    1.51 +
    1.52 +    @Override
    1.53 +    public void disablePageInspector() {
    1.54 +    }
    1.55 +
    1.56 +    @Override
    1.57 +    public void enableLiveHTML() {
    1.58 +    }
    1.59 +
    1.60 +    @Override
    1.61 +    public void close(boolean closeTab) {
    1.62 +    }
    1.63 +
    1.64 +    @Override
    1.65 +    public void setProjectContext(Lookup projectContext) {
    1.66 +        context = projectContext;
    1.67 +    }
    1.68 +    
    1.69      public static enum Kind {
    1.70          ANDROID_DEVICE_DEFAULT,
    1.71          ANDROID_DEVICE_CHROME,
    1.72 @@ -83,26 +133,111 @@
    1.73      @Override
    1.74      public void setURL(URL url) {
    1.75          this.url = url;
    1.76 -        Browser b;
    1.77 -        boolean emulator;
    1.78 -        switch (kind) {
    1.79 -            case ANDROID_DEVICE_CHROME:
    1.80 -                b = Browser.CHROME;
    1.81 -                emulator = false;
    1.82 -                break;
    1.83 -            case ANDROID_DEVICE_DEFAULT:
    1.84 -                b = Browser.DEFAULT;
    1.85 -                emulator = false;
    1.86 -                break;
    1.87 -            case ANDROID_EMULATOR_DEFAULT:
    1.88 -                b = Browser.DEFAULT;
    1.89 -                emulator = false;
    1.90 -                break;
    1.91 -            default:
    1.92 -                throw new IllegalStateException();
    1.93 +        Project project = context.lookup(Project.class);
    1.94 +        openBrowser(COMMAND_RUN_SINGLE, Lookups.singleton(url), kind, project);
    1.95 +    }
    1.96 +    
    1.97 +     public static void openBrowser(String command, final Lookup context, final AndroidBrowser.Kind kind, final Project project) throws IllegalArgumentException {
    1.98 +        final BuildPerformer build = Lookup.getDefault().lookup(BuildPerformer.class);
    1.99 +        String checkAndroid = AndroidActionProvider.checkAndroid();
   1.100 +        if (checkAndroid != null) {
   1.101 +            NotifyDescriptor not = new NotifyDescriptor(
   1.102 +                    checkAndroid,
   1.103 +                    Bundle.ERR_Title(),
   1.104 +                    NotifyDescriptor.OK_CANCEL_OPTION,
   1.105 +                    NotifyDescriptor.ERROR_MESSAGE,
   1.106 +                    null,
   1.107 +                    null);
   1.108 +            Object value = DialogDisplayer.getDefault().notify(not);
   1.109 +            if (NotifyDescriptor.CANCEL_OPTION != value) {
   1.110 +                OptionsDisplayer.getDefault().open("Advanced/MobilePlatforms");
   1.111 +            }
   1.112 +            return;
   1.113          }
   1.114 -        Device d = new AndroidDevice("android", b, emulator);
   1.115 -        d.openUrl(url.toExternalForm());
   1.116 +
   1.117 +        if (COMMAND_RUN.equals(command) || COMMAND_RUN_SINGLE.equals(command)) {
   1.118 +            ProgressUtils.runOffEventDispatchThread(new Runnable() {
   1.119 +                @Override
   1.120 +                public void run() {
   1.121 +                    String checkDevices = checkDevices();
   1.122 +                    while (checkDevices != null) {
   1.123 +                        NotifyDescriptor not = new NotifyDescriptor(
   1.124 +                                checkDevices,
   1.125 +                                Bundle.ERR_Title(),
   1.126 +                                NotifyDescriptor.DEFAULT_OPTION,
   1.127 +                                NotifyDescriptor.ERROR_MESSAGE,
   1.128 +                                null,
   1.129 +                                null);
   1.130 +                        Object value = DialogDisplayer.getDefault().notify(not);
   1.131 +                        if (NotifyDescriptor.CANCEL_OPTION == value) {
   1.132 +                            return;
   1.133 +                        } else {
   1.134 +                            checkDevices = checkDevices();
   1.135 +                        }
   1.136 +                    }
   1.137 +                    Browser b;
   1.138 +                    boolean emulator;
   1.139 +                    if (kind.equals(AndroidBrowser.Kind.ANDROID_DEVICE_DEFAULT)) {
   1.140 +                        b = Browser.DEFAULT;
   1.141 +                        emulator = false;
   1.142 +                    } else if (kind.equals(AndroidBrowser.Kind.ANDROID_DEVICE_CHROME)) {
   1.143 +                        b = Browser.CHROME;
   1.144 +                        emulator = false;
   1.145 +                    } else {
   1.146 +                        b = Browser.DEFAULT;
   1.147 +                        emulator = true;
   1.148 +                    }
   1.149 +                    Device device = new AndroidDevice("android", b, emulator);
   1.150 +
   1.151 +                    device.openUrl(build.getUrl(project, context));
   1.152 +                    
   1.153 +                    if (Browser.CHROME.getName().equals(b.getName())) {
   1.154 +                        try {
   1.155 +                            Thread.sleep(5000);
   1.156 +                        } catch (InterruptedException ex) {
   1.157 +                            Exceptions.printStackTrace(ex);
   1.158 +                        }
   1.159 +                        try {
   1.160 +                            build.startDebugging(device, project, context);
   1.161 +                        } catch (IllegalStateException ex) {
   1.162 +                            LOGGER.log(Level.INFO, ex.getMessage(), ex);
   1.163 +                            SwingUtilities.invokeLater(new Runnable() {
   1.164 +                                @Override
   1.165 +                                public void run() {
   1.166 +                                    JOptionPane.showMessageDialog(
   1.167 +                                            WindowManager.getDefault().getMainWindow(),
   1.168 +                                            Bundle.ERR_WebDebug());
   1.169 +                                }
   1.170 +                            });
   1.171 +                        }
   1.172 +                    }
   1.173 +
   1.174 +                }
   1.175 +
   1.176 +                private String checkDevices() {
   1.177 +                    try {
   1.178 +                        if (kind.equals(AndroidBrowser.Kind.ANDROID_EMULATOR_DEFAULT)) { //NOI18N
   1.179 +                            for (Device dev : PlatformManager.getPlatform(PlatformManager.ANDROID_TYPE).getConnectedDevices()) {
   1.180 +                                if (dev.isEmulator()) {
   1.181 +                                    return null;
   1.182 +                                }
   1.183 +                            }
   1.184 +                            return Bundle.ERR_RunAndroidEmulator();
   1.185 +                        } else {
   1.186 +                            for (Device dev : PlatformManager.getPlatform(PlatformManager.ANDROID_TYPE).getConnectedDevices()) {
   1.187 +                                if (!dev.isEmulator()) {
   1.188 +                                    return null;
   1.189 +                                }
   1.190 +                            }
   1.191 +                            return Bundle.ERR_ConnectAndroidDevice();
   1.192 +                        }
   1.193 +                    } catch (IOException iOException) {
   1.194 +                        Exceptions.printStackTrace(iOException);
   1.195 +                    }
   1.196 +                    return Bundle.ERR_Unknown();
   1.197 +                }
   1.198 +            }, Bundle.LBL_CheckingDevice(), new AtomicBoolean(), false);
   1.199 +        }
   1.200      }
   1.201  
   1.202      @Override
     2.1 --- a/cordova.platforms.android/src/org/netbeans/modules/cordova/platforms/android/EnhancedBrowserImpl.java	Tue Mar 26 10:19:48 2013 +0100
     2.2 +++ b/cordova.platforms.android/src/org/netbeans/modules/cordova/platforms/android/EnhancedBrowserImpl.java	Tue Mar 26 14:42:53 2013 +0100
     2.3 @@ -42,18 +42,8 @@
     2.4  
     2.5  package org.netbeans.modules.cordova.platforms.android;
     2.6  
     2.7 -import java.io.IOException;
     2.8 -import java.util.concurrent.atomic.AtomicBoolean;
     2.9 -import java.util.logging.Level;
    2.10  import java.util.logging.Logger;
    2.11 -import javax.swing.JOptionPane;
    2.12 -import javax.swing.SwingUtilities;
    2.13 -import org.netbeans.api.options.OptionsDisplayer;
    2.14 -import org.netbeans.api.progress.ProgressUtils;
    2.15  import org.netbeans.api.project.Project;
    2.16 -import org.netbeans.modules.cordova.platforms.BuildPerformer;
    2.17 -import org.netbeans.modules.cordova.platforms.Device;
    2.18 -import org.netbeans.modules.cordova.platforms.PlatformManager;
    2.19  import org.netbeans.modules.web.browser.api.WebBrowser;
    2.20  import org.netbeans.modules.web.clientproject.spi.platform.ClientProjectEnhancedBrowserImplementation;
    2.21  import org.netbeans.modules.web.clientproject.spi.platform.ProjectConfigurationCustomizer;
    2.22 @@ -62,11 +52,7 @@
    2.23  import static org.netbeans.spi.project.ActionProvider.COMMAND_RUN;
    2.24  import static org.netbeans.spi.project.ActionProvider.COMMAND_RUN_SINGLE;
    2.25  import org.netbeans.spi.project.ProjectConfigurationProvider;
    2.26 -import org.openide.DialogDisplayer;
    2.27 -import org.openide.NotifyDescriptor;
    2.28 -import org.openide.util.Exceptions;
    2.29  import org.openide.util.Lookup;
    2.30 -import org.openide.windows.WindowManager;
    2.31  
    2.32  /**
    2.33   * @author Jan Becicka
    2.34 @@ -131,106 +117,8 @@
    2.35  
    2.36          @Override
    2.37          public void invokeAction(String command, final Lookup context) throws IllegalArgumentException {
    2.38 -            final BuildPerformer build = Lookup.getDefault().lookup(BuildPerformer.class);
    2.39 -            String checkAndroid = AndroidActionProvider.checkAndroid();
    2.40 -            if (checkAndroid != null) {
    2.41 -                NotifyDescriptor not = new NotifyDescriptor(
    2.42 -                        checkAndroid,
    2.43 -                        Bundle.ERR_Title(),
    2.44 -                        NotifyDescriptor.OK_CANCEL_OPTION,
    2.45 -                        NotifyDescriptor.ERROR_MESSAGE,
    2.46 -                        null,
    2.47 -                        null);
    2.48 -                Object value = DialogDisplayer.getDefault().notify(not);
    2.49 -                if (NotifyDescriptor.CANCEL_OPTION != value) {
    2.50 -                    OptionsDisplayer.getDefault().open("Advanced/MobilePlatforms");
    2.51 -                }
    2.52 -                return;
    2.53 -            }
    2.54 -
    2.55 -            if (COMMAND_RUN.equals(command) || COMMAND_RUN_SINGLE.equals(command)) {
    2.56 -                ProgressUtils.runOffEventDispatchThread(new Runnable() {
    2.57 -                    @Override
    2.58 -                    public void run() {
    2.59 -                        String checkDevices = checkDevices();
    2.60 -                        while (checkDevices != null) {
    2.61 -                            NotifyDescriptor not = new NotifyDescriptor(
    2.62 -                                    checkDevices,
    2.63 -                                    Bundle.ERR_Title(),
    2.64 -                                    NotifyDescriptor.DEFAULT_OPTION,
    2.65 -                                    NotifyDescriptor.ERROR_MESSAGE,
    2.66 -                                    null,
    2.67 -                                    null);
    2.68 -                            Object value = DialogDisplayer.getDefault().notify(not);
    2.69 -                            if (NotifyDescriptor.CANCEL_OPTION == value) {
    2.70 -                                return;
    2.71 -                            } else {
    2.72 -                                checkDevices = checkDevices();
    2.73 -                            }
    2.74 -                        }
    2.75 -                        Browser b;
    2.76 -                        boolean emulator;
    2.77 -                        if (browser.getId().equals(AndroidBrowser.Kind.ANDROID_DEVICE_DEFAULT.toString())) {
    2.78 -                            b=Browser.DEFAULT;
    2.79 -                            emulator = false;
    2.80 -                        } else if (browser.getId().equals(AndroidBrowser.Kind.ANDROID_DEVICE_CHROME.toString())) {
    2.81 -                            b=Browser.CHROME;
    2.82 -                            emulator = false;
    2.83 -                        } else {
    2.84 -                            b=Browser.DEFAULT;
    2.85 -                            emulator = true;
    2.86 -                        }
    2.87 -                        Device device = new AndroidDevice("android", b, emulator);
    2.88 -                        
    2.89 -                        device.openUrl(build.getUrl(project, context));
    2.90 -                        if (Browser.CHROME.getName().equals(b.getName())) {
    2.91 -                            try {
    2.92 -                                Thread.sleep(5000);
    2.93 -                            } catch (InterruptedException ex) {
    2.94 -                                Exceptions.printStackTrace(ex);
    2.95 -                            }
    2.96 -                            try {
    2.97 -                                build.startDebugging(device, project);
    2.98 -                            } catch (IllegalStateException ex) {
    2.99 -                                LOGGER.log(Level.INFO, ex.getMessage(), ex);
   2.100 -                                SwingUtilities.invokeLater(new Runnable() {
   2.101 -                                    @Override
   2.102 -                                    public void run() {
   2.103 -                                        JOptionPane.showMessageDialog(
   2.104 -                                                WindowManager.getDefault().getMainWindow(),
   2.105 -                                                Bundle.ERR_WebDebug());
   2.106 -                                    }
   2.107 -                                });
   2.108 -                            }
   2.109 -                        }
   2.110 -
   2.111 -                    }
   2.112 -
   2.113 -                    private String checkDevices() {
   2.114 -                        try {
   2.115 -                            if (browser.getId().equals(AndroidBrowser.Kind.ANDROID_EMULATOR_DEFAULT.toString())) { //NOI18N
   2.116 -                                for (Device dev : PlatformManager.getPlatform(PlatformManager.ANDROID_TYPE).getConnectedDevices()) {
   2.117 -                                    if (dev.isEmulator()) {
   2.118 -                                        return null;
   2.119 -                                    }
   2.120 -                                }
   2.121 -                                return Bundle.ERR_RunAndroidEmulator();
   2.122 -                            } else {
   2.123 -                                for (Device dev : PlatformManager.getPlatform(PlatformManager.ANDROID_TYPE).getConnectedDevices()) {
   2.124 -                                    if (!dev.isEmulator()) {
   2.125 -                                        return null;
   2.126 -                                    }
   2.127 -                                }
   2.128 -                                return Bundle.ERR_ConnectAndroidDevice();
   2.129 -                            }
   2.130 -                        } catch (IOException iOException) {
   2.131 -                            Exceptions.printStackTrace(iOException);
   2.132 -                        }
   2.133 -                        return Bundle.ERR_Unknown();
   2.134 -                    }
   2.135 -                }, Bundle.LBL_CheckingDevice(), new AtomicBoolean(), false);
   2.136 -            }
   2.137 -        }
   2.138 +            AndroidBrowser.openBrowser(command, context, AndroidBrowser.Kind.valueOf(browser.getId()), project);
   2.139 +         }
   2.140  
   2.141          @Override
   2.142          public boolean isActionEnabled(String command, Lookup context) throws IllegalArgumentException {
     3.1 --- a/cordova.platforms.android/src/org/netbeans/modules/cordova/platforms/android/EnhancedBrowserProviderImpl.java	Tue Mar 26 10:19:48 2013 +0100
     3.2 +++ b/cordova.platforms.android/src/org/netbeans/modules/cordova/platforms/android/EnhancedBrowserProviderImpl.java	Tue Mar 26 14:42:53 2013 +0100
     3.3 @@ -47,6 +47,7 @@
     3.4  import org.netbeans.modules.web.browser.api.WebBrowser;
     3.5  import org.netbeans.modules.web.clientproject.spi.platform.ClientProjectEnhancedBrowserImplementation;
     3.6  import org.netbeans.modules.web.clientproject.spi.platform.ClientProjectEnhancedBrowserProvider;
     3.7 +import org.netbeans.spi.project.LookupProvider;
     3.8  import org.netbeans.spi.project.ProjectServiceProvider;
     3.9  
    3.10  /**
     4.1 --- a/cordova.platforms.ios/src/org/netbeans/modules/cordova/platforms/ios/EnhancedBrowserImpl.java	Tue Mar 26 10:19:48 2013 +0100
     4.2 +++ b/cordova.platforms.ios/src/org/netbeans/modules/cordova/platforms/ios/EnhancedBrowserImpl.java	Tue Mar 26 14:42:53 2013 +0100
     4.3 @@ -123,25 +123,7 @@
     4.4  
     4.5          @Override
     4.6          public void invokeAction(String command, final Lookup context) throws IllegalArgumentException {
     4.7 -            if (!Utilities.isMac()) {
     4.8 -                NotifyDescriptor not = new NotifyDescriptor(
     4.9 -                        Bundle.LBL_NoMac(),
    4.10 -                        Bundle.ERR_Title(),
    4.11 -                        NotifyDescriptor.DEFAULT_OPTION,
    4.12 -                        NotifyDescriptor.ERROR_MESSAGE,
    4.13 -                        null,
    4.14 -                        null);
    4.15 -                DialogDisplayer.getDefault().notify(not);
    4.16 -                return;
    4.17 -            }
    4.18 -            final BuildPerformer build = Lookup.getDefault().lookup(BuildPerformer.class);
    4.19 -            assert build != null;
    4.20 -            ProgressUtils.runOffEventDispatchThread(new Runnable() {
    4.21 -                @Override
    4.22 -                public void run() {
    4.23 -                    IOSDevice.IPHONE.openUrl(build.getUrl(project, context));
    4.24 -                }
    4.25 -            }, Bundle.LBL_Opening(), new AtomicBoolean(), false);
    4.26 +            IOSBrowser.openBrowser(command, context, project);
    4.27          }
    4.28  
    4.29          @Override
     5.1 --- a/cordova.platforms.ios/src/org/netbeans/modules/cordova/platforms/ios/EnhancedBrowserProviderImpl.java	Tue Mar 26 10:19:48 2013 +0100
     5.2 +++ b/cordova.platforms.ios/src/org/netbeans/modules/cordova/platforms/ios/EnhancedBrowserProviderImpl.java	Tue Mar 26 14:42:53 2013 +0100
     5.3 @@ -47,6 +47,7 @@
     5.4  import org.netbeans.modules.web.browser.api.WebBrowser;
     5.5  import org.netbeans.modules.web.clientproject.spi.platform.ClientProjectEnhancedBrowserImplementation;
     5.6  import org.netbeans.modules.web.clientproject.spi.platform.ClientProjectEnhancedBrowserProvider;
     5.7 +import org.netbeans.spi.project.LookupProvider;
     5.8  import org.netbeans.spi.project.ProjectServiceProvider;
     5.9  
    5.10  /**
     6.1 --- a/cordova.platforms.ios/src/org/netbeans/modules/cordova/platforms/ios/IOSBrowser.java	Tue Mar 26 10:19:48 2013 +0100
     6.2 +++ b/cordova.platforms.ios/src/org/netbeans/modules/cordova/platforms/ios/IOSBrowser.java	Tue Mar 26 14:42:53 2013 +0100
     6.3 @@ -44,14 +44,52 @@
     6.4  import java.awt.Component;
     6.5  import java.beans.PropertyChangeListener;
     6.6  import java.net.URL;
     6.7 +import java.util.concurrent.atomic.AtomicBoolean;
     6.8 +import org.netbeans.api.progress.ProgressUtils;
     6.9 +import org.netbeans.api.project.Project;
    6.10 +import org.netbeans.modules.cordova.platforms.BuildPerformer;
    6.11 +import org.netbeans.modules.web.browser.spi.EnhancedBrowser;
    6.12 +import org.netbeans.spi.project.ActionProvider;
    6.13 +import org.openide.DialogDisplayer;
    6.14 +import org.openide.NotifyDescriptor;
    6.15  import org.openide.awt.HtmlBrowser;
    6.16 +import org.openide.util.Lookup;
    6.17 +import org.openide.util.Utilities;
    6.18 +import org.openide.util.lookup.Lookups;
    6.19  
    6.20  /**
    6.21   *
    6.22   * @author Jan Becicka
    6.23   */
    6.24 -public class IOSBrowser extends HtmlBrowser.Impl {
    6.25 +public class IOSBrowser extends HtmlBrowser.Impl implements EnhancedBrowser {
    6.26      private final Kind kind;
    6.27 +    private Lookup projectContext;
    6.28 +
    6.29 +    @Override
    6.30 +    public boolean hasEnhancedMode() {
    6.31 +        return false;
    6.32 +    }
    6.33 +
    6.34 +    @Override
    6.35 +    public void setEnhancedMode(boolean mode) {
    6.36 +    }
    6.37 +
    6.38 +    @Override
    6.39 +    public void disablePageInspector() {
    6.40 +    }
    6.41 +
    6.42 +    @Override
    6.43 +    public void enableLiveHTML() {
    6.44 +    }
    6.45 +
    6.46 +    @Override
    6.47 +    public void close(boolean closeTab) {
    6.48 +    }
    6.49 +
    6.50 +    @Override
    6.51 +    public void setProjectContext(Lookup projectContext) {
    6.52 +        this.projectContext = projectContext;
    6.53 +    }
    6.54      
    6.55      public static enum Kind {
    6.56          IOS_DEVICE_DEFAULT,
    6.57 @@ -81,9 +119,33 @@
    6.58      @Override
    6.59      public void setURL(URL url) {
    6.60          this.url = url;
    6.61 -        IOSDevice.IPHONE.openUrl(url.toExternalForm());
    6.62 +        Project project = projectContext.lookup(Project.class);
    6.63 +        openBrowser(ActionProvider.COMMAND_RUN, Lookups.fixed(url), project);
    6.64      }
    6.65  
    6.66 +    public static void openBrowser(String command, final Lookup context, final Project project) throws IllegalArgumentException {
    6.67 +        if (!Utilities.isMac()) {
    6.68 +            NotifyDescriptor not = new NotifyDescriptor(
    6.69 +                    Bundle.LBL_NoMac(),
    6.70 +                    Bundle.ERR_Title(),
    6.71 +                    NotifyDescriptor.DEFAULT_OPTION,
    6.72 +                    NotifyDescriptor.ERROR_MESSAGE,
    6.73 +                    null,
    6.74 +                    null);
    6.75 +            DialogDisplayer.getDefault().notify(not);
    6.76 +            return;
    6.77 +        }
    6.78 +        final BuildPerformer build = Lookup.getDefault().lookup(BuildPerformer.class);
    6.79 +        assert build != null;
    6.80 +        ProgressUtils.runOffEventDispatchThread(new Runnable() {
    6.81 +            @Override
    6.82 +            public void run() {
    6.83 +                    IOSDevice.IPHONE.openUrl(build.getUrl(project, context));
    6.84 +            }
    6.85 +        }, Bundle.LBL_Opening(), new AtomicBoolean(), false);
    6.86 +    }
    6.87 +    
    6.88 +
    6.89      @Override
    6.90      public URL getURL() {
    6.91          return url;
     7.1 --- a/cordova.platforms/src/org/netbeans/modules/cordova/platforms/BuildPerformer.java	Tue Mar 26 10:19:48 2013 +0100
     7.2 +++ b/cordova.platforms/src/org/netbeans/modules/cordova/platforms/BuildPerformer.java	Tue Mar 26 14:42:53 2013 +0100
     7.3 @@ -62,7 +62,7 @@
     7.4      
     7.5      public boolean isPhoneGapBuild(Project p);
     7.6      
     7.7 -    public void startDebugging(Device device, Project p);
     7.8 +    public void startDebugging(Device device, Project p, Lookup context);
     7.9      
    7.10      public void stopDebugging();
    7.11      
     8.1 --- a/cordova/src/org/netbeans/modules/cordova/CordovaPerformer.java	Tue Mar 26 10:19:48 2013 +0100
     8.2 +++ b/cordova/src/org/netbeans/modules/cordova/CordovaPerformer.java	Tue Mar 26 14:42:53 2013 +0100
     8.3 @@ -45,6 +45,7 @@
     8.4  import java.io.IOException;
     8.5  import java.io.InputStream;
     8.6  import java.io.OutputStream;
     8.7 +import java.net.URL;
     8.8  import java.util.Properties;
     8.9  import java.util.prefs.Preferences;
    8.10  import org.apache.tools.ant.module.api.support.ActionUtils;
    8.11 @@ -232,6 +233,11 @@
    8.12  
    8.13      @Override
    8.14      public String getUrl(Project p, Lookup context) {
    8.15 +        URL url = context.lookup(URL.class);
    8.16 +        if (url!=null) {
    8.17 +            //TODO: hack to workaround #221791
    8.18 +            return url.toExternalForm().replace("localhost", WebUtils.getLocalhostInetAddress().getHostAddress());
    8.19 +        }
    8.20          if (org.netbeans.modules.cordova.project.ClientProjectUtilities.isUsingEmbeddedServer(p)) {
    8.21              WebServer.getWebserver().start(p, ClientProjectUtilities.getSiteRoot(p), ClientProjectUtilities.getWebContextRoot(p));
    8.22          } else {
    8.23 @@ -256,9 +262,9 @@
    8.24      }
    8.25  
    8.26      @Override
    8.27 -    public void startDebugging(Device device, Project p) {
    8.28 +    public void startDebugging(Device device, Project p, Lookup context) {
    8.29          transport = device.getPlatform().getDebugTransport();
    8.30 -        transport.setBaseUrl(getUrl(p));
    8.31 +        transport.setBaseUrl(getUrl(p, context));
    8.32          transport.attach();
    8.33          try {
    8.34              Thread.sleep(1000);