diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 678483779b0..490ec66c18f 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -6,6 +6,7 @@ #include "atom/browser/atom_browser_context.h" #include "atom/common/api/api_messages.h" +#include "atom/common/native_mate_converters/gfx_converter.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/string16_converter.h" #include "atom/common/native_mate_converters/value_converter.h" @@ -31,11 +32,13 @@ v8::Persistent template_; WebContents::WebContents(content::WebContents* web_contents) : content::WebContentsObserver(web_contents), - guest_instance_id_(-1) { + guest_instance_id_(-1), + auto_size_enabled_(false) { } WebContents::WebContents(const mate::Dictionary& options) - : guest_instance_id_(-1) { + : guest_instance_id_(-1), + auto_size_enabled_(false) { options.Get("guestInstances", &guest_instance_id_); content::WebContents::CreateParams params(AtomBrowserContext::Get()); @@ -106,17 +109,19 @@ void WebContents::WebContentsDestroyed() { void WebContents::WillAttach(content::WebContents* embedder_web_contents, const base::DictionaryValue& extra_params) { - LOG(ERROR) << "WillAttach"; + embedder_web_contents_ = embedder_web_contents; + extra_params_.reset(extra_params.DeepCopy()); } content::WebContents* WebContents::CreateNewGuestWindow( const content::WebContents::CreateParams& create_params) { - LOG(ERROR) << "CreateNewGuestWindow"; return nullptr; } void WebContents::DidAttach() { - LOG(ERROR) << "DidAttach"; + base::ListValue args; + args.Append(extra_params_.release()); + Emit("internal-did-attach", args); } int WebContents::GetGuestInstanceID() const { @@ -125,29 +130,30 @@ int WebContents::GetGuestInstanceID() const { void WebContents::ElementSizeChanged(const gfx::Size& old_size, const gfx::Size& new_size) { - LOG(ERROR) << "ElementSizeChanged"; + element_size_ = new_size; } void WebContents::GuestSizeChanged(const gfx::Size& old_size, const gfx::Size& new_size) { - LOG(ERROR) << "GuestSizeChanged"; + if (!auto_size_enabled_) + return; + guest_size_ = new_size; + GuestSizeChangedDueToAutoSize(old_size, new_size); } void WebContents::RequestPointerLockPermission( bool user_gesture, bool last_unlocked_by_target, - const base::Callback& callback) { + const base::Callback& callback) { callback.Run(true); } void WebContents::RegisterDestructionCallback( const DestructionCallback& callback) { - LOG(ERROR) << "RegisterDestructionCallback"; destruction_callback_ = callback; } void WebContents::Destroy() { - LOG(ERROR) << "Destroy"; if (storage_) { if (!destruction_callback_.is_null()) destruction_callback_.Run(); @@ -248,6 +254,33 @@ bool WebContents::SendIPCMessage(const base::string16& channel, return Send(new AtomViewMsg_Message(routing_id(), channel, args)); } +void WebContents::SetAutoSize(bool enabled, + const gfx::Size& min_size, + const gfx::Size& max_size) { + min_auto_size_ = min_size; + min_auto_size_.SetToMin(max_size); + max_auto_size_ = max_size; + max_auto_size_.SetToMax(min_size); + + enabled &= !min_auto_size_.IsEmpty() && !max_auto_size_.IsEmpty(); + if (!enabled && !auto_size_enabled_) + return; + + auto_size_enabled_ = enabled; + + if (!attached()) + return; + + content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); + if (auto_size_enabled_) { + rvh->EnableAutoResize(min_auto_size_, max_auto_size_); + } else { + rvh->DisableAutoResize(element_size_); + guest_size_ = element_size_; + GuestSizeChangedDueToAutoSize(guest_size_, element_size_); + } +} + mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( v8::Isolate* isolate) { if (template_.IsEmpty()) @@ -274,6 +307,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( .SetMethod("isCrashed", &WebContents::IsCrashed) .SetMethod("_executeJavaScript", &WebContents::ExecuteJavaScript) .SetMethod("_send", &WebContents::SendIPCMessage) + .SetMethod("setAutoSize", &WebContents::SetAutoSize) .Build()); return mate::ObjectTemplateBuilder( @@ -283,7 +317,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder( void WebContents::OnRendererMessage(const base::string16& channel, const base::ListValue& args) { // webContents.emit(channel, new Event(), args...); - Emit(base::UTF16ToUTF8(channel), args, web_contents(), NULL); + Emit(base::UTF16ToUTF8(channel), args); } void WebContents::OnRendererMessageSync(const base::string16& channel, @@ -293,6 +327,16 @@ void WebContents::OnRendererMessageSync(const base::string16& channel, Emit(base::UTF16ToUTF8(channel), args, web_contents(), message); } +void WebContents::GuestSizeChangedDueToAutoSize(const gfx::Size& old_size, + const gfx::Size& new_size) { + base::ListValue args; + args.AppendInteger(old_size.width()); + args.AppendInteger(old_size.height()); + args.AppendInteger(new_size.width()); + args.AppendInteger(new_size.height()); + Emit("size-changed", args); +} + // static mate::Handle WebContents::CreateFrom( v8::Isolate* isolate, content::WebContents* web_contents) { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 433d67deb2f..a0e47a6006e 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -56,6 +56,14 @@ class WebContents : public mate::EventEmitter, bool SendIPCMessage(const base::string16& channel, const base::ListValue& args); + // Toggles autosize mode for corresponding . + void SetAutoSize(bool enabled, + const gfx::Size& min_size, + const gfx::Size& max_size); + + // Returns whether this guest has an associated embedder. + bool attached() const { return !!embedder_web_contents_; } + content::WebContents* web_contents() const { return content::WebContentsObserver::web_contents(); } @@ -96,7 +104,7 @@ class WebContents : public mate::EventEmitter, virtual void RequestPointerLockPermission( bool user_gesture, bool last_unlocked_by_target, - const base::Callback& callback) override; + const base::Callback& callback) override; virtual void RegisterDestructionCallback( const DestructionCallback& callback) override; @@ -110,14 +118,42 @@ class WebContents : public mate::EventEmitter, const base::ListValue& args, IPC::Message* message); + void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size, + const gfx::Size& new_size); + // Unique ID for a guest WebContents. int guest_instance_id_; DestructionCallback destruction_callback_; + // The extra parameters associated with this guest view passed + // in from JavaScript. This will typically be the view instance ID, + // the API to use, and view-specific parameters. These parameters + // are passed along to new guests that are created from this guest. + scoped_ptr extra_params_; + // Stores the WebContents that managed by this class. scoped_ptr storage_; + // The WebContents that attaches this guest view. + content::WebContents* embedder_web_contents_; + + // The size of the container element. + gfx::Size element_size_; + + // The size of the guest content. Note: In autosize mode, the container + // element may not match the size of the guest. + gfx::Size guest_size_; + + // Indicates whether autosize mode is enabled or not. + bool auto_size_enabled_; + + // The maximum size constraints of the container element in autosize mode. + gfx::Size max_auto_size_; + + // The minimum size constraints of the container element in autosize mode. + gfx::Size min_auto_size_; + DISALLOW_COPY_AND_ASSIGN(WebContents); }; diff --git a/atom/browser/api/lib/web-contents.coffee b/atom/browser/api/lib/web-contents.coffee index 744cf51ab8c..24f7375cb99 100644 --- a/atom/browser/api/lib/web-contents.coffee +++ b/atom/browser/api/lib/web-contents.coffee @@ -22,6 +22,14 @@ module.exports.wrap = (webContents) -> else webContents.once 'did-finish-load', @_executeJavaScript.bind(this, code) + # Init guest web view. + webContents.on 'internal-did-attach', (event, params) -> + min = width: params.minwidth, height: params.minheight + max = width: params.maxwidth, height: params.maxheight + @setAutoSize params.autosize, min, max + if params.src + @loadUrl params.src + # The processId and routingId and identify a webContents. webContents.getId = -> "#{@getProcessId()}-#{@getRoutingId()}" webContents.equal = (other) -> @getId() is other.getId() @@ -32,10 +40,10 @@ module.exports.wrap = (webContents) -> process.emit 'ATOM_BROWSER_RELEASE_RENDER_VIEW', "#{processId}-#{routingId}" # Dispatch IPC messages to the ipc module. - webContents.on 'ipc-message', (event, channel, args...) => + webContents.on 'ipc-message', (event, channel, args...) -> Object.defineProperty event, 'sender', value: webContents ipc.emit channel, event, args... - webContents.on 'ipc-message-sync', (event, channel, args...) => + webContents.on 'ipc-message-sync', (event, channel, args...) -> Object.defineProperty event, 'returnValue', set: (value) -> event.sendReply JSON.stringify(value) Object.defineProperty event, 'sender', value: webContents ipc.emit channel, event, args... diff --git a/atom/browser/default_app/index.html b/atom/browser/default_app/index.html index 0d9c59a857f..db06acafc15 100644 --- a/atom/browser/default_app/index.html +++ b/atom/browser/default_app/index.html @@ -56,7 +56,7 @@ - +