From ee45f0e8bcda427becbce3d257bea6f3496b6b28 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 27 Apr 2015 15:11:37 +0800 Subject: [PATCH 01/10] Upgrade libchromiumcontent --- script/lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/config.py b/script/lib/config.py index ed050590ff9d8..d149446c1d727 100644 --- a/script/lib/config.py +++ b/script/lib/config.py @@ -7,7 +7,7 @@ BASE_URL = 'http://gh-contractor-zcbenz.s3.amazonaws.com/libchromiumcontent' -LIBCHROMIUMCONTENT_COMMIT = '0529dc17ca2f950b671cf12f82260cc397b4cebb' +LIBCHROMIUMCONTENT_COMMIT = '0fb4fbe55f5a967b960644f0fdc2013668d5a46a' PLATFORM = { 'cygwin': 'win32', From b527846ee41abeb35d5f30d10340be10b47ff179 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 12:28:27 +0800 Subject: [PATCH 02/10] Use our new way to restart renderer process As a side effect, it will also restart the renderer process of webview tag guests. --- atom/browser/atom_browser_client.cc | 24 ++++++++++++------------ atom/browser/atom_browser_client.h | 9 +++++---- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 2a246f2276478..df32284cc1ee2 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -119,22 +119,22 @@ void AtomBrowserClient::OverrideWebkitPrefs( window->OverrideWebkitPrefs(prefs); } -bool AtomBrowserClient::ShouldSwapBrowsingInstancesForNavigation( - content::SiteInstance* site_instance, - const GURL& current_url, - const GURL& new_url) { - if (site_instance->HasProcess()) - dying_render_process_ = site_instance->GetProcess(); - - // Restart renderer process for all navigations, this relies on a patch to - // Chromium: http://git.io/_PaNyg. - return true; -} - std::string AtomBrowserClient::GetApplicationLocale() { return l10n_util::GetApplicationLocale(""); } +void AtomBrowserClient::OverrideSiteInstanceForNavigation( + content::BrowserContext* browser_context, + content::SiteInstance* current_instance, + const GURL& url, + content::SiteInstance** new_instance) { + if (current_instance->HasProcess()) + dying_render_process_ = current_instance->GetProcess(); + + // Restart renderer process for all navigations. + *new_instance = content::SiteInstance::CreateForURL(browser_context, url); +} + void AtomBrowserClient::AppendExtraCommandLineSwitches( base::CommandLine* command_line, int child_process_id) { diff --git a/atom/browser/atom_browser_client.h b/atom/browser/atom_browser_client.h index 828b3f78f78a9..629ac9640ca2c 100644 --- a/atom/browser/atom_browser_client.h +++ b/atom/browser/atom_browser_client.h @@ -27,11 +27,12 @@ class AtomBrowserClient : public brightray::BrowserClient { void ResourceDispatcherHostCreated() override; void OverrideWebkitPrefs(content::RenderViewHost* render_view_host, content::WebPreferences* prefs) override; - bool ShouldSwapBrowsingInstancesForNavigation( - content::SiteInstance* site_instance, - const GURL& current_url, - const GURL& new_url) override; std::string GetApplicationLocale() override; + void OverrideSiteInstanceForNavigation( + content::BrowserContext* browser_context, + content::SiteInstance* current_instance, + const GURL& dest_url, + content::SiteInstance** new_instance); void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; From d8adbc08754e399114f80d74c1c2a86f569d91ed Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 12:35:14 +0800 Subject: [PATCH 03/10] NULL => nullptr --- atom/browser/atom_browser_client.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index df32284cc1ee2..c3bcb946caf98 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -49,7 +49,7 @@ struct FindByProcessId { } // namespace AtomBrowserClient::AtomBrowserClient() - : dying_render_process_(NULL) { + : dying_render_process_(nullptr) { } AtomBrowserClient::~AtomBrowserClient() { @@ -139,7 +139,7 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( base::CommandLine* command_line, int child_process_id) { WindowList* list = WindowList::GetInstance(); - NativeWindow* window = NULL; + NativeWindow* window = nullptr; // Find the owner of this child process. WindowList::const_iterator iter = std::find_if( @@ -150,7 +150,7 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( // If the render process is a newly started one, which means the window still // uses the old going-to-be-swapped render process, then we try to find the // window from the swapped render process. - if (window == NULL && dying_render_process_ != NULL) { + if (!window && dying_render_process_) { child_process_id = dying_render_process_->GetID(); WindowList::const_iterator iter = std::find_if( list->begin(), list->end(), FindByProcessId(child_process_id)); @@ -158,7 +158,7 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( window = *iter; } - if (window != NULL) { + if (window) { window->AppendExtraCommandLineSwitches(command_line, child_process_id); } else { // Append commnad line arguments for guest web view. @@ -180,7 +180,7 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( } } - dying_render_process_ = NULL; + dying_render_process_ = nullptr; } brightray::BrowserMainParts* AtomBrowserClient::OverrideCreateBrowserMainParts( From 36c4b1705dd5af7b7eeae7051b69b0f7bbb38c7e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 15:30:31 +0800 Subject: [PATCH 04/10] Update guest process id when navigating --- atom/browser/atom_browser_client.cc | 16 ++++++++++--- atom/browser/web_view_manager.cc | 36 +++++++++++++++++++++++------ atom/browser/web_view_manager.h | 4 ++++ 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index c3bcb946caf98..8f1bb41d136d3 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -151,11 +151,21 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( // uses the old going-to-be-swapped render process, then we try to find the // window from the swapped render process. if (!window && dying_render_process_) { - child_process_id = dying_render_process_->GetID(); + int dying_process_id = dying_render_process_->GetID(); WindowList::const_iterator iter = std::find_if( - list->begin(), list->end(), FindByProcessId(child_process_id)); - if (iter != list->end()) + list->begin(), list->end(), FindByProcessId(dying_process_id)); + if (iter != list->end()) { window = *iter; + child_process_id = dying_process_id; + } else { + // It appears that the dying process doesn't belong to a BrowserWindow, + // then it must be a guest process, we should update its process ID in the + // WebViewManager here. + auto child_process = content::RenderProcessHost::FromID(child_process_id); + // Update the process ID in webview guests. + WebViewManager::UpdateGuestProcessID(dying_render_process_, + child_process); + } } if (window) { diff --git a/atom/browser/web_view_manager.cc b/atom/browser/web_view_manager.cc index 91124f9119040..9de3088a0bf53 100644 --- a/atom/browser/web_view_manager.cc +++ b/atom/browser/web_view_manager.cc @@ -10,18 +10,40 @@ namespace atom { -// static -bool WebViewManager::GetInfoForProcess(content::RenderProcessHost* process, - WebViewInfo* info) { +namespace { + +WebViewManager* GetManagerFromProcess(content::RenderProcessHost* process) { if (!process) - return false; + return nullptr; auto context = process->GetBrowserContext(); if (!context) - return false; - auto manager = context->GetGuestManager(); + return nullptr; + return static_cast(context->GetGuestManager()); +} + +} // namespace + +// static +bool WebViewManager::GetInfoForProcess(content::RenderProcessHost* process, + WebViewInfo* info) { + auto manager = GetManagerFromProcess(process); if (!manager) return false; - return static_cast(manager)->GetInfo(process->GetID(), info); + return manager->GetInfo(process->GetID(), info); +} + +// static +void WebViewManager::UpdateGuestProcessID( + content::RenderProcessHost* old_process, + content::RenderProcessHost* new_process) { + auto manager = GetManagerFromProcess(old_process); + if (manager) { + base::AutoLock auto_lock(manager->lock_); + int old_id = old_process->GetID(); + int new_id = new_process->GetID(); + manager->webview_info_map_[new_id] = manager->webview_info_map_[old_id]; + manager->webview_info_map_.erase(old_id); + } } WebViewManager::WebViewManager(content::BrowserContext* context) { diff --git a/atom/browser/web_view_manager.h b/atom/browser/web_view_manager.h index 87f3c56994332..2327b2e02b4c8 100644 --- a/atom/browser/web_view_manager.h +++ b/atom/browser/web_view_manager.h @@ -34,6 +34,10 @@ class WebViewManager : public content::BrowserPluginGuestManager { static bool GetInfoForProcess(content::RenderProcessHost* process, WebViewInfo* info); + // Updates the guest process ID. + static void UpdateGuestProcessID(content::RenderProcessHost* old_process, + content::RenderProcessHost* new_process); + explicit WebViewManager(content::BrowserContext* context); virtual ~WebViewManager(); From 3ff2959f0ca02ab48a1bf556991e8ce0f3c8ee1a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 15:49:26 +0800 Subject: [PATCH 05/10] spec: Native modules should work after navigation in webview --- spec/fixtures/pages/native-module.html | 9 +++++++++ spec/webview-spec.coffee | 13 +++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 spec/fixtures/pages/native-module.html diff --git a/spec/fixtures/pages/native-module.html b/spec/fixtures/pages/native-module.html new file mode 100644 index 0000000000000..a0ae0fe7592d8 --- /dev/null +++ b/spec/fixtures/pages/native-module.html @@ -0,0 +1,9 @@ + + + + + + diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index 1936731f3541d..ea50f632b31c2 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -47,6 +47,19 @@ describe ' tag', -> webview.src = "file://#{fixtures}/pages/d.html" document.body.appendChild webview + it 'loads native modules when navigation happens', (done) -> + listener = (e) -> + webview.removeEventListener 'did-finish-load', listener + listener2 = (e) -> + assert.equal e.message, 'function' + done() + webview.addEventListener 'console-message', listener2 + webview.src = "file://#{fixtures}/pages/native-module.html" + webview.addEventListener 'did-finish-load', listener + webview.setAttribute 'nodeintegration', 'on' + webview.src = "file://#{fixtures}/pages/native-module.html" + document.body.appendChild webview + describe 'preload attribute', -> it 'loads the script before other scripts in window', (done) -> listener = (e) -> From 4c78f98da6ea95dc157cecc63d379b33ba1878f6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 17:26:00 +0800 Subject: [PATCH 06/10] Check if it is guest process before updating process ID --- atom/browser/atom_browser_client.cc | 4 ++-- atom/browser/web_view_manager.cc | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 8f1bb41d136d3..0ee2c7f931705 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -159,8 +159,8 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( child_process_id = dying_process_id; } else { // It appears that the dying process doesn't belong to a BrowserWindow, - // then it must be a guest process, we should update its process ID in the - // WebViewManager here. + // then it might be a guest process, if it is we should update its + // process ID in the WebViewManager. auto child_process = content::RenderProcessHost::FromID(child_process_id); // Update the process ID in webview guests. WebViewManager::UpdateGuestProcessID(dying_render_process_, diff --git a/atom/browser/web_view_manager.cc b/atom/browser/web_view_manager.cc index 9de3088a0bf53..77a772da9adfb 100644 --- a/atom/browser/web_view_manager.cc +++ b/atom/browser/web_view_manager.cc @@ -41,6 +41,8 @@ void WebViewManager::UpdateGuestProcessID( base::AutoLock auto_lock(manager->lock_); int old_id = old_process->GetID(); int new_id = new_process->GetID(); + if (!ContainsKey(manager->webview_info_map_, old_id)) + return; manager->webview_info_map_[new_id] = manager->webview_info_map_[old_id]; manager->webview_info_map_.erase(old_id); } From 2f1683445b8c7e089576114432575fe5e2ef2807 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 17:26:25 +0800 Subject: [PATCH 07/10] Only append command line params for renderer process --- atom/browser/atom_browser_client.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 0ee2c7f931705..c897d5d19af96 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -138,6 +138,10 @@ void AtomBrowserClient::OverrideSiteInstanceForNavigation( void AtomBrowserClient::AppendExtraCommandLineSwitches( base::CommandLine* command_line, int child_process_id) { + std::string process_type = command_line->GetSwitchValueASCII("type"); + if (process_type != "renderer") + return; + WindowList* list = WindowList::GetInstance(); NativeWindow* window = nullptr; From 0143a4548869c1e8201ef3c3b6c2e098d5dd5140 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 21:28:30 +0800 Subject: [PATCH 08/10] Implement our own NavigationController --- atom/browser/api/atom_api_web_contents.cc | 63 +-------------- atom/browser/api/atom_api_web_contents.h | 11 +-- .../api/lib/navigation-controller.coffee | 76 +++++++++++++++++++ atom/browser/api/lib/web-contents.coffee | 11 ++- filenames.gypi | 1 + 5 files changed, 89 insertions(+), 73 deletions(-) create mode 100644 atom/browser/api/lib/navigation-controller.coffee diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 5853b10d17c85..4e27e1e64e597 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -18,6 +18,7 @@ #include "atom/common/native_mate_converters/value_converter.h" #include "base/strings/utf_string_conversions.h" #include "brightray/browser/inspectable_web_contents.h" +#include "brightray/browser/media/media_stream_devices_controller.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_entry.h" @@ -30,7 +31,6 @@ #include "content/public/browser/web_contents.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" -#include "vendor/brightray/browser/media/media_stream_devices_controller.h" #include "atom/common/node_includes.h" @@ -312,8 +312,7 @@ void WebContents::WebContentsDestroyed() { void WebContents::NavigationEntryCommitted( const content::LoadCommittedDetails& load_details) { - auto entry = web_contents()->GetController().GetLastCommittedEntry(); - entry->SetVirtualURL(load_details.entry->GetOriginalRequestURL()); + Emit("navigation-entry-commited", load_details.entry->GetURL()); } void WebContents::DidAttach(int guest_proxy_routing_id) { @@ -385,13 +384,6 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) { web_contents()->GetController().LoadURLWithParams(params); } -GURL WebContents::GetURL() const { - auto entry = web_contents()->GetController().GetLastCommittedEntry(); - if (!entry) - return GURL::EmptyGURL(); - return entry->GetVirtualURL(); -} - base::string16 WebContents::GetTitle() const { return web_contents()->GetTitle(); } @@ -415,46 +407,8 @@ void WebContents::Stop() { web_contents()->Stop(); } -void WebContents::Reload(const mate::Dictionary& options) { - // Navigating to a URL would always restart the renderer process, we want this - // because normal reloading will break our node integration. - // This is done by AtomBrowserClient::ShouldSwapProcessesForNavigation. - LoadURL(GetURL(), options); -} - -void WebContents::ReloadIgnoringCache(const mate::Dictionary& options) { - // Hack to remove pending entries that ignores cache and treated as a fresh - // load. +void WebContents::ReloadIgnoringCache() { web_contents()->GetController().ReloadIgnoringCache(false); - Reload(options); -} - -bool WebContents::CanGoBack() const { - return web_contents()->GetController().CanGoBack(); -} - -bool WebContents::CanGoForward() const { - return web_contents()->GetController().CanGoForward(); -} - -bool WebContents::CanGoToOffset(int offset) const { - return web_contents()->GetController().CanGoToOffset(offset); -} - -void WebContents::GoBack() { - web_contents()->GetController().GoBack(); -} - -void WebContents::GoForward() { - web_contents()->GetController().GoForward(); -} - -void WebContents::GoToIndex(int index) { - web_contents()->GetController().GoToIndex(index); -} - -void WebContents::GoToOffset(int offset) { - web_contents()->GetController().GoToOffset(offset); } int WebContents::GetRoutingID() const { @@ -599,21 +553,12 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("destroy", &WebContents::Destroy) .SetMethod("isAlive", &WebContents::IsAlive) .SetMethod("_loadUrl", &WebContents::LoadURL) - .SetMethod("getUrl", &WebContents::GetURL) .SetMethod("getTitle", &WebContents::GetTitle) .SetMethod("getFavicon", &WebContents::GetFavicon) .SetMethod("isLoading", &WebContents::IsLoading) .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse) - .SetMethod("stop", &WebContents::Stop) - .SetMethod("_reload", &WebContents::Reload) + .SetMethod("_stop", &WebContents::Stop) .SetMethod("_reloadIgnoringCache", &WebContents::ReloadIgnoringCache) - .SetMethod("canGoBack", &WebContents::CanGoBack) - .SetMethod("canGoForward", &WebContents::CanGoForward) - .SetMethod("canGoToOffset", &WebContents::CanGoToOffset) - .SetMethod("goBack", &WebContents::GoBack) - .SetMethod("goForward", &WebContents::GoForward) - .SetMethod("goToIndex", &WebContents::GoToIndex) - .SetMethod("goToOffset", &WebContents::GoToOffset) .SetMethod("getRoutingId", &WebContents::GetRoutingID) .SetMethod("getProcessId", &WebContents::GetProcessID) .SetMethod("isCrashed", &WebContents::IsCrashed) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 4ccf3d8caee3d..371c338708cc1 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -47,21 +47,12 @@ class WebContents : public mate::EventEmitter, void Destroy(); bool IsAlive() const; void LoadURL(const GURL& url, const mate::Dictionary& options); - GURL GetURL() const; base::string16 GetTitle() const; gfx::Image GetFavicon() const; bool IsLoading() const; bool IsWaitingForResponse() const; void Stop(); - void Reload(const mate::Dictionary& options); - void ReloadIgnoringCache(const mate::Dictionary& options); - bool CanGoBack() const; - bool CanGoForward() const; - bool CanGoToOffset(int offset) const; - void GoBack(); - void GoForward(); - void GoToIndex(int index); - void GoToOffset(int offset); + void ReloadIgnoringCache(); int GetRoutingID() const; int GetProcessID() const; bool IsCrashed() const; diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee new file mode 100644 index 0000000000000..8f193de13e8a4 --- /dev/null +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -0,0 +1,76 @@ +# JavaScript implementation of Chromium's NavigationController. +# Instead of relying on Chromium for history control, we compeletely do history +# control on user land, and only rely on WebContents.loadUrl for navigation. +# This helps us avoid Chromium's various optimizations so we can ensure renderer +# process is restarted everytime. +class NavigationController + constructor: (@webContents) -> + @history = [] + @currentIndex = -1 + @pendingIndex = -1 + + @webContents.on 'navigation-entry-commited', (event, url) => + if @pendingIndex >= 0 # Go to index. + @currentIndex = @pendingIndex + @pendingIndex = -1 + @history[@currentIndex] = url + else # Normal navigation. + @history = @history.slice 0, @currentIndex + 1 # Clear history. + if @history[@currentIndex] isnt url + @currentIndex++ + @history.push url + + loadUrl: (url, options={}) -> + @pendingIndex = -1 + @webContents._loadUrl url, options + + getUrl: -> + if @currentIndex is -1 + '' + else + @history[@currentIndex] + + stop: -> + @pendingIndex = -1 + @webContents._stop() + + reload: -> + @pendingIndex = @currentIndex + @webContents._loadUrl @getUrl(), {} + + reloadIgnoringCache: -> + @webContents._reloadIgnoringCache() # Rely on WebContents to clear cache. + @reload() + + canGoBack: -> + @currentIndex > 0 + + canGoForward: -> + @currentIndex < @history.length + + canGoToIndex: (index) -> + index >=0 and index < @history.length + + canGoToOffset: (offset) -> + @canGoToIndex @currentIndex + offset + + goBack: -> + return unless @canGoBack() + @pendingIndex = @currentIndex - 1 + @webContents._loadUrl @history[@pendingIndex], {} + + goForward: -> + return unless @canGoForward() + @pendingIndex = @currentIndex + 1 + @webContents._loadUrl @history[@pendingIndex], {} + + goToIndex: (index) -> + return unless @canGoToIndex index + @pendingIndex = index + @webContents._loadUrl @history[@pendingIndex], {} + + goToOffset: (offset) -> + return unless @canGoToOffset offset + @goToIndex @currentIndex + offset + +module.exports = NavigationController diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index cb772fd8c27e2..e249ccfb808dc 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -1,4 +1,5 @@ EventEmitter = require('events').EventEmitter +NavigationController = require './navigation-controller' binding = process.atomBinding 'web_contents' ipc = require 'ipc' @@ -26,10 +27,12 @@ module.exports.wrap = (webContents) -> webContents.getId = -> "#{@getProcessId()}-#{@getRoutingId()}" webContents.equal = (other) -> @getId() is other.getId() - # Provide a default parameter for |urlOptions|. - webContents.loadUrl = (url, urlOptions={}) -> @_loadUrl url, urlOptions - webContents.reload = (urlOptions={}) -> @_reload urlOptions - webContents.reloadIgnoringCache = (urlOptions={}) -> @_reloadIgnoringCache urlOptions + # The navigation controller. + controller = new NavigationController(webContents) + webContents.controller = controller + for name, method of NavigationController.prototype when method instanceof Function + do (name, method) -> + webContents[name] = -> method.apply controller, arguments # Translate |disposition| to string for 'new-window' event. webContents.on '-new-window', (args..., disposition) -> diff --git a/filenames.gypi b/filenames.gypi index 586d67c177293..093136805b242 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -18,6 +18,7 @@ 'atom/browser/api/lib/ipc.coffee', 'atom/browser/api/lib/menu.coffee', 'atom/browser/api/lib/menu-item.coffee', + 'atom/browser/api/lib/navigation-controller.coffee', 'atom/browser/api/lib/power-monitor.coffee', 'atom/browser/api/lib/protocol.coffee', 'atom/browser/api/lib/screen.coffee', From 16b2f08cd30064ff4bf1e3d6b931c9fb6ca4480b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 21:31:48 +0800 Subject: [PATCH 09/10] Don't use Chromium's history list --- atom/browser/api/atom_api_web_contents.cc | 2 ++ atom/browser/native_window.cc | 1 + 2 files changed, 3 insertions(+) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 4e27e1e64e597..0400e9457e37f 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -140,6 +140,7 @@ content::WebContents* WebContents::OpenURLFromTab( load_url_params.is_renderer_initiated = params.is_renderer_initiated; load_url_params.transferred_global_request_id = params.transferred_global_request_id; + load_url_params.should_clear_history_list = true; web_contents()->GetController().LoadURLWithParams(load_url_params); return web_contents(); @@ -380,6 +381,7 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) { blink::WebReferrerPolicyDefault); params.transition_type = ui::PAGE_TRANSITION_TYPED; + params.should_clear_history_list = true; params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE; web_contents()->GetController().LoadURLWithParams(params); } diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index c2ed3b0fe79ee..0f757e8c619f4 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -565,6 +565,7 @@ content::WebContents* NativeWindow::OpenURLFromTab( load_url_params.is_renderer_initiated = params.is_renderer_initiated; load_url_params.transferred_global_request_id = params.transferred_global_request_id; + load_url_params.should_clear_history_list = true; source->GetController().LoadURLWithParams(load_url_params); return source; From dde791d475dd1a4e2952709922b017a6fc08fba1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 26 Apr 2015 22:29:51 +0800 Subject: [PATCH 10/10] Allow calling goBack for multiple times --- .../api/lib/navigation-controller.coffee | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/atom/browser/api/lib/navigation-controller.coffee b/atom/browser/api/lib/navigation-controller.coffee index 8f193de13e8a4..75f9dd2097ca0 100644 --- a/atom/browser/api/lib/navigation-controller.coffee +++ b/atom/browser/api/lib/navigation-controller.coffee @@ -10,15 +10,15 @@ class NavigationController @pendingIndex = -1 @webContents.on 'navigation-entry-commited', (event, url) => - if @pendingIndex >= 0 # Go to index. - @currentIndex = @pendingIndex - @pendingIndex = -1 - @history[@currentIndex] = url - else # Normal navigation. + if @pendingIndex is -1 # Normal navigation. @history = @history.slice 0, @currentIndex + 1 # Clear history. if @history[@currentIndex] isnt url @currentIndex++ @history.push url + else # Go to index. + @currentIndex = @pendingIndex + @pendingIndex = -1 + @history[@currentIndex] = url loadUrl: (url, options={}) -> @pendingIndex = -1 @@ -43,10 +43,10 @@ class NavigationController @reload() canGoBack: -> - @currentIndex > 0 + @getActiveIndex() > 0 canGoForward: -> - @currentIndex < @history.length + @getActiveIndex() < @history.length - 1 canGoToIndex: (index) -> index >=0 and index < @history.length @@ -56,12 +56,12 @@ class NavigationController goBack: -> return unless @canGoBack() - @pendingIndex = @currentIndex - 1 + @pendingIndex = @getActiveIndex() - 1 @webContents._loadUrl @history[@pendingIndex], {} goForward: -> return unless @canGoForward() - @pendingIndex = @currentIndex + 1 + @pendingIndex = @getActiveIndex() + 1 @webContents._loadUrl @history[@pendingIndex], {} goToIndex: (index) -> @@ -73,4 +73,7 @@ class NavigationController return unless @canGoToOffset offset @goToIndex @currentIndex + offset + getActiveIndex: -> + if @pendingIndex is -1 then @currentIndex else @pendingIndex + module.exports = NavigationController