diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 5045efae2a37..9115cbc82ad1 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -286,8 +286,14 @@ bool WebContents::IsAlive() const { return web_contents() != NULL; } -void WebContents::LoadURL(const GURL& url) { +void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) { content::NavigationController::LoadURLParams params(url); + + GURL http_referrer; + if (options.Get("httpreferrer", &http_referrer)) + params.referrer = content::Referrer(http_referrer.GetAsReferrer(), + blink::WebReferrerPolicyDefault); + params.transition_type = content::PAGE_TRANSITION_TYPED; params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE; web_contents()->GetController().LoadURLWithParams(params); @@ -313,15 +319,15 @@ void WebContents::Stop() { web_contents()->Stop(); } -void WebContents::Reload() { +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()); + LoadURL(GetURL(), options); } -void WebContents::ReloadIgnoringCache() { - Reload(); +void WebContents::ReloadIgnoringCache(const mate::Dictionary& options) { + Reload(options); } bool WebContents::CanGoBack() const { @@ -438,14 +444,14 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate) .SetMethod("destroy", &WebContents::Destroy) .SetMethod("isAlive", &WebContents::IsAlive) - .SetMethod("loadUrl", &WebContents::LoadURL) + .SetMethod("_loadUrl", &WebContents::LoadURL) .SetMethod("getUrl", &WebContents::GetURL) .SetMethod("getTitle", &WebContents::GetTitle) .SetMethod("isLoading", &WebContents::IsLoading) .SetMethod("isWaitingForResponse", &WebContents::IsWaitingForResponse) .SetMethod("stop", &WebContents::Stop) - .SetMethod("reload", &WebContents::Reload) - .SetMethod("reloadIgnoringCache", &WebContents::ReloadIgnoringCache) + .SetMethod("_reload", &WebContents::Reload) + .SetMethod("_reloadIgnoringCache", &WebContents::ReloadIgnoringCache) .SetMethod("canGoBack", &WebContents::CanGoBack) .SetMethod("canGoForward", &WebContents::CanGoForward) .SetMethod("canGoToOffset", &WebContents::CanGoToOffset) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index c29221008c89..7f6a6971901d 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -41,14 +41,14 @@ class WebContents : public mate::EventEmitter, void Destroy(); bool IsAlive() const; - void LoadURL(const GURL& url); + void LoadURL(const GURL& url, const mate::Dictionary& options); GURL GetURL() const; base::string16 GetTitle() const; bool IsLoading() const; bool IsWaitingForResponse() const; void Stop(); - void Reload(); - void ReloadIgnoringCache(); + void Reload(const mate::Dictionary& options); + void ReloadIgnoringCache(const mate::Dictionary& options); bool CanGoBack() const; bool CanGoForward() const; bool CanGoToOffset(int offset) const; diff --git a/atom/browser/api/lib/browser-window.coffee b/atom/browser/api/lib/browser-window.coffee index e855a93524fc..3d89659444c6 100644 --- a/atom/browser/api/lib/browser-window.coffee +++ b/atom/browser/api/lib/browser-window.coffee @@ -90,8 +90,8 @@ BrowserWindow::send = -> @webContents.send.apply @webContents, arguments # Be compatible with old API. BrowserWindow::restart = -> @webContents.reload() BrowserWindow::getUrl = -> @webContents.getUrl() -BrowserWindow::reload = -> @webContents.reload() -BrowserWindow::reloadIgnoringCache = -> @webContents.reloadIgnoringCache() +BrowserWindow::reload = -> @webContents.reload.apply @webContents, arguments +BrowserWindow::reloadIgnoringCache = -> @webContents.reloadIgnoringCache.apply @webContents, arguments BrowserWindow::getPageTitle = -> @webContents.getTitle() BrowserWindow::isLoading = -> @webContents.isLoading() BrowserWindow::isWaitingForResponse = -> @webContents.isWaitingForResponse() diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index e22d5e01c2b7..5ed80a54ab01 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -26,6 +26,11 @@ 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 + # Translate |disposition| to string for 'new-window' event. webContents.on '-new-window', (args..., disposition) -> disposition = diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index a5c5d021f401..db8ed44848eb 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -47,7 +47,10 @@ createGuest = (embedder, params) -> max = width: params.maxwidth, height: params.maxheight @setAutoSize params.autosize, min, max if params.src - @loadUrl params.src + if params.httpreferrer + @loadUrl params.src, {httpreferrer: params.httpreferrer} + else + @loadUrl params.src if params.allowtransparency? @setAllowTransparency params.allowtransparency diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 59de54bbf2f0..348f3ab332ed 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -227,6 +227,16 @@ NativeWindowViews::NativeWindowViews(content::WebContents* web_contents, use_content_size_) bounds = ContentBoundsToWindowBounds(bounds); +#if defined(OS_WIN) + if (!has_frame_) { + // Set Window style so that we get a minimize and maximize animation when + // frameless. + DWORD frame_style = WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | + WS_CAPTION; + ::SetWindowLong(GetAcceleratedWidget(), GWL_STYLE, frame_style); + } +#endif + if(has_frame_) { window_->set_frame_type(views::Widget::FrameType::FRAME_TYPE_FORCE_NATIVE); window_->FrameTypeChanged(); diff --git a/atom/renderer/lib/web-view.coffee b/atom/renderer/lib/web-view.coffee index ee11683d9a52..f27be54ab556 100644 --- a/atom/renderer/lib/web-view.coffee +++ b/atom/renderer/lib/web-view.coffee @@ -197,6 +197,12 @@ class WebView # No setter. enumerable: true + @httpreferrer = @webviewNode.getAttribute 'httpreferrer' + Object.defineProperty @webviewNode, 'httpreferrer', + get: => @httpreferrer + set: (value) => @webviewNode.setAttribute 'httpreferrer', value + enumerable: true + # The purpose of this mutation observer is to catch assignment to the src # attribute without any changes to its value. This is useful in the case # where the webview guest has crashed and navigating to the same address @@ -211,7 +217,7 @@ class WebView params = attributes: true, attributeOldValue: true, - attributeFilter: ['src', 'partition'] + attributeFilter: ['src', 'partition', 'httpreferrer'] @srcAndPartitionObserver.observe @webviewNode, params # This observer monitors mutations to attributes of the and @@ -245,6 +251,21 @@ class WebView return unless @guestInstanceId guestViewInternal.setAllowTransparency @guestInstanceId, @allowtransparency + else if name is 'httpreferrer' + oldValue ?= '' + newValue ?= '' + + if newValue == '' and oldValue != '' + @webviewNode.setAttribute 'httpreferrer', oldValue + + @httpreferrer = newValue + + result = {} + # If the httpreferrer changes treat it as though the src changes and reload + # the page with the new httpreferrer. + @parseSrcAttribute result + + throw result.error if result.error? else if name is 'src' # We treat null attribute (attribute removed) and the empty string as # one case. @@ -364,7 +385,8 @@ class WebView return # Navigate to |this.src|. - remote.getGuestWebContents(@guestInstanceId).loadUrl @src + urlOptions = if @httpreferrer then {@httpreferrer} else {} + remote.getGuestWebContents(@guestInstanceId).loadUrl @src, urlOptions parseAttributes: -> return unless @elementAttached @@ -447,6 +469,7 @@ class WebView # set via this.onAttach(). storagePartitionId: @partition.toAttribute() userAgentOverride: @userAgentOverride + httpreferrer: @httpreferrer attachWindow: (guestInstanceId, isNewWindow) -> @guestInstanceId = guestInstanceId diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 0b5f63973843..d4650b683f51 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -104,6 +104,14 @@ When the guest page doesn't have node integration this script will still have access to all Node APIs, but global objects injected by Node will be deleted after this script has done execution. +### httpreferrer + +```html + +``` + +Sets the referrer URL for the guest page. + ## Methods ### ``.getUrl() diff --git a/spec/fixtures/pages/referrer.html b/spec/fixtures/pages/referrer.html new file mode 100644 index 000000000000..673b244ce165 --- /dev/null +++ b/spec/fixtures/pages/referrer.html @@ -0,0 +1,7 @@ + + + + + diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index 71c4854d5ff9..f14cee53c998 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -58,6 +58,18 @@ describe ' tag', -> webview.src = "file://#{fixtures}/pages/e.html" document.body.appendChild webview + describe 'httpreferrer attribute', -> + it 'sets the referrer url', (done) -> + referrer = 'http://github.com/' + listener = (e) -> + assert.equal e.message, referrer + webview.removeEventListener 'console-message', listener + done() + webview.addEventListener 'console-message', listener + webview.setAttribute 'httpreferrer', referrer + webview.src = "file://#{fixtures}/pages/referrer.html" + document.body.appendChild webview + describe 'new-window event', -> it 'emits when window.open is called', (done) -> webview.addEventListener 'new-window', (e) ->