#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"
#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"
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) {
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();
}
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 {
.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)
--- /dev/null
+# 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
EventEmitter = require('events').EventEmitter
+NavigationController = require './navigation-controller'
binding = process.atomBinding 'web_contents'
ipc = require 'ipc'
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) ->