Update to the new algorithm of setting webview size

This commit is contained in:
Cheng Zhao 2015-05-29 11:12:55 +08:00
parent 3e720bd611
commit bdf73fcd4c
6 changed files with 126 additions and 28 deletions

View file

@ -44,12 +44,40 @@
#include "atom/common/node_includes.h"
namespace mate {
template<>
struct Converter<atom::api::SetSizeParams> {
static bool FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
atom::api::SetSizeParams* out) {
mate::Dictionary params;
if (!ConvertFromV8(isolate, val, &params))
return false;
bool autosize;
if (params.Get("enableAutoSize", &autosize))
out->enable_auto_size.reset(new bool(true));
gfx::Size size;
if (params.Get("min", &size))
out->min_size.reset(new gfx::Size(size));
if (params.Get("max", &size))
out->max_size.reset(new gfx::Size(size));
return true;
}
};
} // namespace mate
namespace atom {
namespace api {
namespace {
const int kDefaultWidth = 300;
const int kDefaultHeight = 300;
v8::Persistent<v8::ObjectTemplate> template_;
// Get the window that has the |guest| embedded.
@ -85,7 +113,8 @@ WebContents::WebContents(content::WebContents* web_contents)
element_instance_id_(-1),
guest_opaque_(true),
guest_host_(nullptr),
auto_size_enabled_(false) {
auto_size_enabled_(false),
is_full_page_plugin_(false) {
}
WebContents::WebContents(const mate::Dictionary& options)
@ -93,7 +122,8 @@ WebContents::WebContents(const mate::Dictionary& options)
element_instance_id_(-1),
guest_opaque_(true),
guest_host_(nullptr),
auto_size_enabled_(false) {
auto_size_enabled_(false),
is_full_page_plugin_(false) {
options.Get("guestInstanceId", &guest_instance_id_);
auto browser_context = AtomBrowserContext::Get();
@ -612,31 +642,57 @@ 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) {
void WebContents::SetSize(const SetSizeParams& params) {
bool enable_auto_size =
params.enable_auto_size ? *params.enable_auto_size : auto_size_enabled_;
gfx::Size min_size = params.min_size ? *params.min_size : min_auto_size_;
gfx::Size max_size = params.max_size ? *params.max_size : max_auto_size_;
if (params.normal_size)
normal_size_ = *params.normal_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;
enable_auto_size &= !min_auto_size_.IsEmpty() && !max_auto_size_.IsEmpty();
content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
if (auto_size_enabled_) {
if (enable_auto_size) {
// Autosize is being enabled.
rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
normal_size_.SetSize(0, 0);
} else {
rvh->DisableAutoResize(element_size_);
guest_size_ = element_size_;
GuestSizeChangedDueToAutoSize(guest_size_, element_size_);
// Autosize is being disabled.
// Use default width/height if missing from partially defined normal size.
if (normal_size_.width() && !normal_size_.height())
normal_size_.set_height(GetDefaultSize().height());
if (!normal_size_.width() && normal_size_.height())
normal_size_.set_width(GetDefaultSize().width());
gfx::Size new_size;
if (!normal_size_.IsEmpty()) {
new_size = normal_size_;
} else if (!guest_size_.IsEmpty()) {
new_size = guest_size_;
} else {
new_size = GetDefaultSize();
}
if (auto_size_enabled_) {
// Autosize was previously enabled.
rvh->DisableAutoResize(new_size);
GuestSizeChangedDueToAutoSize(guest_size_, new_size);
} else {
// Autosize was already disabled.
guest_host_->SizeContents(new_size);
}
guest_size_ = new_size;
}
auto_size_enabled_ = enable_auto_size;
}
void WebContents::SetAllowTransparency(bool allow) {
@ -727,7 +783,7 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
.SetMethod("replace", &WebContents::Replace)
.SetMethod("replaceMisspelling", &WebContents::ReplaceMisspelling)
.SetMethod("_send", &WebContents::SendIPCMessage)
.SetMethod("setAutoSize", &WebContents::SetAutoSize)
.SetMethod("setSize", &WebContents::SetSize)
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
.SetMethod("isGuest", &WebContents::is_guest)
.SetMethod("hasServiceWorker", &WebContents::HasServiceWorker)
@ -760,6 +816,16 @@ void WebContents::GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
new_size.width(), new_size.height());
}
gfx::Size WebContents::GetDefaultSize() const {
if (is_full_page_plugin_) {
// Full page plugins default to the size of the owner's viewport.
return embedder_web_contents_->GetRenderWidgetHostView()
->GetVisibleViewportSize();
} else {
return gfx::Size(kDefaultWidth, kDefaultHeight);
}
}
// static
mate::Handle<WebContents> WebContents::CreateFrom(
v8::Isolate* isolate, content::WebContents* web_contents) {

View file

@ -33,6 +33,22 @@ class WebDialogHelper;
namespace api {
// A struct of parameters for SetSize(). The parameters are all declared as
// scoped pointers since they are all optional. Null pointers indicate that the
// parameter has not been provided, and the last used value should be used. Note
// that when |enable_auto_size| is true, providing |normal_size| is not
// meaningful. This is because the normal size of the guestview is overridden
// whenever autosizing occurs.
struct SetSizeParams {
SetSizeParams() {}
~SetSizeParams() {}
scoped_ptr<bool> enable_auto_size;
scoped_ptr<gfx::Size> min_size;
scoped_ptr<gfx::Size> max_size;
scoped_ptr<gfx::Size> normal_size;
};
class WebContents : public mate::EventEmitter,
public content::BrowserPluginGuestDelegate,
public content::WebContentsDelegate,
@ -89,10 +105,9 @@ class WebContents : public mate::EventEmitter,
bool SendIPCMessage(const base::string16& channel,
const base::ListValue& args);
// Toggles autosize mode for corresponding <webview>.
void SetAutoSize(bool enabled,
const gfx::Size& min_size,
const gfx::Size& max_size);
// Used to toggle autosize mode for this GuestView, and set both the automatic
// and normal sizes.
void SetSize(const SetSizeParams& params);
// Sets the transparency of the guest.
void SetAllowTransparency(bool allow);
@ -217,9 +232,17 @@ class WebContents : public mate::EventEmitter,
const base::ListValue& args,
IPC::Message* message);
// This method is invoked when the contents auto-resized to give the container
// an opportunity to match it if it wishes.
//
// This gives the derived class an opportunity to inform its container element
// or perform other actions.
void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
const gfx::Size& new_size);
// Returns the default size of the guestview.
gfx::Size GetDefaultSize() const;
scoped_ptr<WebDialogHelper> web_dialog_helper_;
scoped_ptr<AtomJavaScriptDialogManager> dialog_manager_;
@ -258,6 +281,12 @@ class WebContents : public mate::EventEmitter,
// The minimum size constraints of the container element in autosize mode.
gfx::Size min_auto_size_;
// The size that will be used when autosize mode is disabled.
gfx::Size normal_size_;
// Whether the guest view is inside a plugin document.
bool is_full_page_plugin_;
DISALLOW_COPY_AND_ASSIGN(WebContents);
};

View file

@ -60,7 +60,7 @@ createGuest = (embedder, params) ->
@viewInstanceId = params.instanceId
min = width: params.minwidth, height: params.minheight
max = width: params.maxwidth, height: params.maxheight
@setAutoSize params.autosize, min, max
@setSize params.autosize, min, max
if params.src
opts = {}
@ -132,8 +132,8 @@ ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_ATTACH_GUEST', (event, elementInstanceId,
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', (event, id) ->
destroyGuest event.sender, id
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_AUTO_SIZE', (event, id, params) ->
guestInstances[id]?.guest.setAutoSize params.enableAutoSize, params.min, params.max
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', (event, id, params) ->
guestInstances[id]?.guest.setSize params
ipc.on 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', (event, id, allowtransparency) ->
guestInstances[id]?.guest.setAllowTransparency allowtransparency

View file

@ -67,8 +67,8 @@ module.exports =
destroyGuest: (guestInstanceId) ->
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_DESTROY_GUEST', guestInstanceId
setAutoSize: (guestInstanceId, params) ->
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_AUTO_SIZE', guestInstanceId, params
setSize: (guestInstanceId, params) ->
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_SIZE', guestInstanceId, params
setAllowTransparency: (guestInstanceId, allowtransparency) ->
ipc.send 'ATOM_SHELL_GUEST_VIEW_MANAGER_SET_ALLOW_TRANSPARENCY', guestInstanceId, allowtransparency

View file

@ -72,7 +72,7 @@ class AutosizeDimensionAttribute extends WebViewAttribute
handleMutation: (oldValue, newValue) ->
return unless @webViewImpl.guestInstanceId
guestViewInternal.setAutoSize @webViewImpl.guestInstanceId,
guestViewInternal.setSize @webViewImpl.guestInstanceId,
enableAutoSize: @webViewImpl.attributes[webViewConstants.ATTRIBUTE_AUTOSIZE].getValue()
min:
width: parseInt @webViewImpl.attributes[webViewConstants.ATTRIBUTE_MINWIDTH].getValue() || 0

View file

@ -107,6 +107,9 @@ class WebViewImpl
minWidth = @attributes[webViewConstants.ATTRIBUTE_MINWIDTH].getValue() | width
minHeight = @attributes[webViewConstants.ATTRIBUTE_MINHEIGHT].getValue() | width
minWidth = Math.min minWidth, maxWidth
minHeight = Math.min minHeight, maxHeight
if not @attributes[webViewConstants.ATTRIBUTE_AUTOSIZE].getValue() or
(newWidth >= minWidth and
newWidth <= maxWidth and