mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Compare commits
28 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
47e6d4bf84 | ||
|
ce8bb0b577 | ||
|
c27da0e7b1 | ||
|
260526953e | ||
|
861c26e48c | ||
|
f615d24edd | ||
|
8c8c96778b | ||
|
207d4922ea | ||
|
b207934543 | ||
|
d9d61f13a6 | ||
|
d66017718b | ||
|
eba024daac | ||
|
ada8355206 | ||
|
f931d0858c | ||
|
6ca48c1dc7 | ||
|
d4b589c46e | ||
|
ef11636d7a | ||
|
7b49af6182 | ||
|
41b717075e | ||
|
e912bfaa77 | ||
|
8e0674eda6 | ||
|
99ca5135d5 | ||
|
a69659d5af | ||
|
30b602cd8d | ||
|
75b5dd4d81 | ||
|
c962e07a5b | ||
|
4821788089 | ||
|
b21a64544e |
@@ -7,5 +7,5 @@
|
||||
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
|
||||
|
||||
{
|
||||
'chromium_checkout': '59d4494849b405682265ed5d3f5164573b9a939b',
|
||||
'chromium_checkout': 'refs/tags/43.0.2357.130',
|
||||
}
|
||||
|
10
cef.gyp
10
cef.gyp
@@ -392,6 +392,7 @@
|
||||
'<(DEPTH)/testing/gtest.gyp:gtest',
|
||||
'<(DEPTH)/third_party/icu/icu.gyp:icui18n',
|
||||
'<(DEPTH)/third_party/icu/icu.gyp:icuuc',
|
||||
'<(DEPTH)/third_party/zlib/google/zip.gyp:zip',
|
||||
'<(DEPTH)/ui/base/ui_base.gyp:ui_base',
|
||||
'libcef_dll_wrapper',
|
||||
],
|
||||
@@ -415,6 +416,7 @@
|
||||
'tests/unittests/display_unittest.cc',
|
||||
'tests/unittests/dom_unittest.cc',
|
||||
'tests/unittests/download_unittest.cc',
|
||||
'tests/unittests/draggable_regions_unittest.cc',
|
||||
'tests/unittests/frame_unittest.cc',
|
||||
'tests/unittests/geolocation_unittest.cc',
|
||||
'tests/unittests/jsdialog_unittest.cc',
|
||||
@@ -428,6 +430,7 @@
|
||||
'tests/unittests/request_context_unittest.cc',
|
||||
'tests/unittests/request_handler_unittest.cc',
|
||||
'tests/unittests/request_unittest.cc',
|
||||
'tests/unittests/resource_manager_unittest.cc',
|
||||
'tests/unittests/routing_test_handler.cc',
|
||||
'tests/unittests/routing_test_handler.h',
|
||||
'tests/unittests/run_all_unittests.cc',
|
||||
@@ -594,6 +597,10 @@
|
||||
],
|
||||
},
|
||||
],
|
||||
# Need to fix their ODR violations. See issue #1604.
|
||||
'ldflags!': [
|
||||
'-Wl,--detect-odr-violations',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
@@ -1012,6 +1019,8 @@
|
||||
'libcef/browser/speech_recognition_manager_delegate.h',
|
||||
'libcef/browser/ssl_cert_principal_impl.cc',
|
||||
'libcef/browser/ssl_cert_principal_impl.h',
|
||||
'libcef/browser/ssl_host_state_delegate.cc',
|
||||
'libcef/browser/ssl_host_state_delegate.h',
|
||||
'libcef/browser/ssl_info_impl.cc',
|
||||
'libcef/browser/ssl_info_impl.h',
|
||||
'libcef/browser/stream_impl.cc',
|
||||
@@ -1063,6 +1072,7 @@
|
||||
'libcef/common/drag_data_impl.h',
|
||||
'libcef/common/http_header_utils.cc',
|
||||
'libcef/common/http_header_utils.h',
|
||||
'libcef/common/json_impl.cc',
|
||||
'libcef/common/main_delegate.cc',
|
||||
'libcef/common/main_delegate.h',
|
||||
'libcef/common/net_resource_provider.cc',
|
||||
|
@@ -69,6 +69,7 @@
|
||||
'include/wrapper/cef_closure_task.h',
|
||||
'include/wrapper/cef_helpers.h',
|
||||
'include/wrapper/cef_message_router.h',
|
||||
'include/wrapper/cef_resource_manager.h',
|
||||
'include/wrapper/cef_stream_resource_handler.h',
|
||||
'include/wrapper/cef_xml_object.h',
|
||||
'include/wrapper/cef_zip_archive.h',
|
||||
@@ -126,6 +127,7 @@
|
||||
'libcef_dll/wrapper/cef_byte_read_handler.cc',
|
||||
'libcef_dll/wrapper/cef_closure_task.cc',
|
||||
'libcef_dll/wrapper/cef_message_router.cc',
|
||||
'libcef_dll/wrapper/cef_resource_manager.cc',
|
||||
'libcef_dll/wrapper/cef_stream_resource_handler.cc',
|
||||
'libcef_dll/wrapper/cef_xml_object.cc',
|
||||
'libcef_dll/wrapper/cef_zip_archive.cc',
|
||||
|
@@ -132,22 +132,6 @@
|
||||
#error Please add support for your compiler in cef_build.h
|
||||
#endif
|
||||
|
||||
// Annotate a virtual method indicating it must be overriding a virtual
|
||||
// method in the parent class.
|
||||
// Use like:
|
||||
// virtual void foo() OVERRIDE;
|
||||
#ifndef OVERRIDE
|
||||
#if defined(__clang__) || defined(COMPILER_MSVC)
|
||||
#define OVERRIDE override
|
||||
#elif defined(COMPILER_GCC) && __cplusplus >= 201103 && \
|
||||
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40700
|
||||
// GCC 4.7 supports explicit virtual overrides when C++11 support is enabled.
|
||||
#define OVERRIDE override
|
||||
#else
|
||||
#define OVERRIDE
|
||||
#endif
|
||||
#endif // OVERRIDE
|
||||
|
||||
// Annotate a function indicating the caller must examine the return value.
|
||||
// Use like:
|
||||
// int foo() WARN_UNUSED_RESULT;
|
||||
@@ -183,4 +167,23 @@
|
||||
|
||||
#endif // !BUILDING_CEF_SHARED
|
||||
|
||||
// Annotate a virtual method indicating it must be overriding a virtual method
|
||||
// in the parent class.
|
||||
// Use like:
|
||||
// void foo() OVERRIDE;
|
||||
// NOTE: This define should only be used in classes exposed to the client since
|
||||
// C++11 support may not be enabled in client applications. CEF internal classes
|
||||
// should use the `override` keyword directly.
|
||||
#ifndef OVERRIDE
|
||||
#if defined(__clang__) || defined(COMPILER_MSVC)
|
||||
#define OVERRIDE override
|
||||
#elif defined(COMPILER_GCC) && __cplusplus >= 201103 && \
|
||||
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40700
|
||||
// GCC 4.7 supports explicit virtual overrides when C++11 support is enabled.
|
||||
#define OVERRIDE override
|
||||
#else
|
||||
#define OVERRIDE
|
||||
#endif
|
||||
#endif // OVERRIDE
|
||||
|
||||
#endif // CEF_INCLUDE_BASE_CEF_BUILD_H_
|
||||
|
@@ -175,6 +175,13 @@ CEF_EXPORT void cef_quit_message_loop();
|
||||
///
|
||||
CEF_EXPORT void cef_set_osmodal_loop(int osModalLoop);
|
||||
|
||||
///
|
||||
// Call during process startup to enable High-DPI support on Windows 7 or newer.
|
||||
// Older versions of Windows should be left DPI-unaware because they do not
|
||||
// support DirectWrite and GDI fonts are kerned very badly.
|
||||
///
|
||||
CEF_EXPORT void cef_enable_highdpi_support();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -66,6 +66,17 @@ typedef struct _cef_drag_handler_t {
|
||||
int (CEF_CALLBACK *on_drag_enter)(struct _cef_drag_handler_t* self,
|
||||
struct _cef_browser_t* browser, struct _cef_drag_data_t* dragData,
|
||||
cef_drag_operations_mask_t mask);
|
||||
|
||||
///
|
||||
// Called whenever draggable regions for the browser window change. These can
|
||||
// be specified using the '-webkit-app-region: drag/no-drag' CSS-property. If
|
||||
// draggable regions are never defined in a document this function will also
|
||||
// never be called. If the last draggable region is removed from a document
|
||||
// this function will be called with an NULL vector.
|
||||
///
|
||||
void (CEF_CALLBACK *on_draggable_regions_changed)(
|
||||
struct _cef_drag_handler_t* self, struct _cef_browser_t* browser,
|
||||
size_t regionsCount, cef_draggable_region_t const* regions);
|
||||
} cef_drag_handler_t;
|
||||
|
||||
|
||||
|
@@ -122,6 +122,26 @@ CEF_EXPORT cef_string_userfree_t cef_uridecode(const cef_string_t* text,
|
||||
CEF_EXPORT int cef_parse_csscolor(const cef_string_t* string, int strict,
|
||||
cef_color_t* color);
|
||||
|
||||
// Parses the specified |json_string| and returns a dictionary or list
|
||||
// representation. If JSON parsing fails this function returns NULL.
|
||||
CEF_EXPORT struct _cef_value_t* cef_parse_json(const cef_string_t* json_string,
|
||||
cef_json_parser_options_t options);
|
||||
|
||||
// Parses the specified |json_string| and returns a dictionary or list
|
||||
// representation. If JSON parsing fails this function returns NULL and
|
||||
// populates |error_code_out| and |error_msg_out| with an error code and a
|
||||
// formatted error message respectively.
|
||||
CEF_EXPORT struct _cef_value_t* cef_parse_jsonand_return_error(
|
||||
const cef_string_t* json_string, cef_json_parser_options_t options,
|
||||
cef_json_parser_error_t* error_code_out, cef_string_t* error_msg_out);
|
||||
|
||||
// Generates a JSON string from the specified root |node| which should be a
|
||||
// dictionary or list value. Returns an NULL string on failure. This function
|
||||
// requires exclusive access to |node| including any underlying data.
|
||||
// The resulting string must be freed by calling cef_string_userfree_free().
|
||||
CEF_EXPORT cef_string_userfree_t cef_write_json(struct _cef_value_t* node,
|
||||
cef_json_writer_options_t options);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -124,6 +124,14 @@ void CefQuitMessageLoop();
|
||||
/*--cef()--*/
|
||||
void CefSetOSModalLoop(bool osModalLoop);
|
||||
|
||||
///
|
||||
// Call during process startup to enable High-DPI support on Windows 7 or newer.
|
||||
// Older versions of Windows should be left DPI-unaware because they do not
|
||||
// support DirectWrite and GDI fonts are kerned very badly.
|
||||
///
|
||||
/*--cef(capi_name=cef_enable_highdpi_support)--*/
|
||||
void CefEnableHighDPISupport();
|
||||
|
||||
///
|
||||
// Implement this interface to provide handler implementations. Methods will be
|
||||
// called by the process and/or thread indicated.
|
||||
|
@@ -113,17 +113,17 @@ class CefRefCount {
|
||||
///
|
||||
#define IMPLEMENT_REFCOUNTING(ClassName) \
|
||||
public: \
|
||||
void AddRef() const { \
|
||||
void AddRef() const OVERRIDE { \
|
||||
ref_count_.AddRef(); \
|
||||
} \
|
||||
bool Release() const { \
|
||||
bool Release() const OVERRIDE { \
|
||||
if (ref_count_.Release()) { \
|
||||
delete static_cast<const ClassName*>(this); \
|
||||
return true; \
|
||||
} \
|
||||
return false; \
|
||||
} \
|
||||
bool HasOneRef() const { \
|
||||
bool HasOneRef() const OVERRIDE { \
|
||||
return ref_count_.HasOneRef(); \
|
||||
} \
|
||||
private: \
|
||||
|
@@ -61,6 +61,18 @@ class CefDragHandler : public virtual CefBase {
|
||||
virtual bool OnDragEnter(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> dragData,
|
||||
DragOperationsMask mask) { return false; }
|
||||
|
||||
///
|
||||
// Called whenever draggable regions for the browser window change. These can
|
||||
// be specified using the '-webkit-app-region: drag/no-drag' CSS-property. If
|
||||
// draggable regions are never defined in a document this method will also
|
||||
// never be called. If the last draggable region is removed from a document
|
||||
// this method will be called with an empty vector.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnDraggableRegionsChanged(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
const std::vector<CefDraggableRegion>& regions) {}
|
||||
};
|
||||
|
||||
#endif // CEF_INCLUDE_CEF_DRAG_HANDLER_H_
|
||||
|
@@ -123,4 +123,28 @@ bool CefParseCSSColor(const CefString& string,
|
||||
bool strict,
|
||||
cef_color_t& color);
|
||||
|
||||
// Parses the specified |json_string| and returns a dictionary or list
|
||||
// representation. If JSON parsing fails this method returns NULL.
|
||||
/*--cef()--*/
|
||||
CefRefPtr<CefValue> CefParseJSON(const CefString& json_string,
|
||||
cef_json_parser_options_t options);
|
||||
|
||||
// Parses the specified |json_string| and returns a dictionary or list
|
||||
// representation. If JSON parsing fails this method returns NULL and populates
|
||||
// |error_code_out| and |error_msg_out| with an error code and a formatted error
|
||||
// message respectively.
|
||||
/*--cef()--*/
|
||||
CefRefPtr<CefValue> CefParseJSONAndReturnError(
|
||||
const CefString& json_string,
|
||||
cef_json_parser_options_t options,
|
||||
cef_json_parser_error_t& error_code_out,
|
||||
CefString& error_msg_out);
|
||||
|
||||
// Generates a JSON string from the specified root |node| which should be a
|
||||
// dictionary or list value. Returns an empty string on failure. This method
|
||||
// requires exclusive access to |node| including any underlying data.
|
||||
/*--cef()--*/
|
||||
CefString CefWriteJSON(CefRefPtr<CefValue> node,
|
||||
cef_json_writer_options_t options);
|
||||
|
||||
#endif // CEF_INCLUDE_CEF_PARSER_H_
|
||||
|
@@ -148,7 +148,7 @@ class CefRunnableMethod : public CefTask {
|
||||
traits_.ReleaseCallee(obj);
|
||||
}
|
||||
|
||||
virtual void Execute() {
|
||||
void Execute() OVERRIDE {
|
||||
if (obj_)
|
||||
DispatchToMethod(obj_, meth_, params_);
|
||||
}
|
||||
@@ -256,7 +256,7 @@ class CefRunnableFunction : public CefTask {
|
||||
~CefRunnableFunction() {
|
||||
}
|
||||
|
||||
virtual void Execute() {
|
||||
void Execute() OVERRIDE {
|
||||
if (function_)
|
||||
DispatchToFunction(function_, params_);
|
||||
}
|
||||
|
@@ -1263,6 +1263,21 @@ typedef struct _cef_size_t {
|
||||
int height;
|
||||
} cef_size_t;
|
||||
|
||||
///
|
||||
// Structure representing a draggable region.
|
||||
///
|
||||
typedef struct _cef_draggable_region_t {
|
||||
///
|
||||
// Bounds of the region.
|
||||
///
|
||||
cef_rect_t bounds;
|
||||
|
||||
///
|
||||
// True (1) this this region is draggable and false (0) otherwise.
|
||||
///
|
||||
int draggable;
|
||||
} cef_draggable_region_t;
|
||||
|
||||
///
|
||||
// Existing process IDs.
|
||||
///
|
||||
@@ -2113,6 +2128,70 @@ typedef enum {
|
||||
UU_REPLACE_PLUS_WITH_SPACE = 16,
|
||||
} cef_uri_unescape_rule_t;
|
||||
|
||||
///
|
||||
// Options that can be passed to CefParseJSON.
|
||||
///
|
||||
typedef enum {
|
||||
///
|
||||
// Parses the input strictly according to RFC 4627. See comments in Chromium's
|
||||
// base/json/json_reader.h file for known limitations/deviations from the RFC.
|
||||
///
|
||||
JSON_PARSER_RFC = 0,
|
||||
|
||||
///
|
||||
// Allows commas to exist after the last element in structures.
|
||||
///
|
||||
JSON_PARSER_ALLOW_TRAILING_COMMAS = 1 << 0,
|
||||
} cef_json_parser_options_t;
|
||||
|
||||
///
|
||||
// Error codes that can be returned from CefParseJSONAndReturnError.
|
||||
///
|
||||
typedef enum {
|
||||
JSON_NO_ERROR = 0,
|
||||
JSON_INVALID_ESCAPE,
|
||||
JSON_SYNTAX_ERROR,
|
||||
JSON_UNEXPECTED_TOKEN,
|
||||
JSON_TRAILING_COMMA,
|
||||
JSON_TOO_MUCH_NESTING,
|
||||
JSON_UNEXPECTED_DATA_AFTER_ROOT,
|
||||
JSON_UNSUPPORTED_ENCODING,
|
||||
JSON_UNQUOTED_DICTIONARY_KEY,
|
||||
JSON_PARSE_ERROR_COUNT
|
||||
} cef_json_parser_error_t;
|
||||
|
||||
///
|
||||
// Options that can be passed to CefWriteJSON.
|
||||
///
|
||||
typedef enum {
|
||||
///
|
||||
// Default behavior.
|
||||
///
|
||||
JSON_WRITER_DEFAULT = 0,
|
||||
|
||||
///
|
||||
// This option instructs the writer that if a Binary value is encountered,
|
||||
// the value (and key if within a dictionary) will be omitted from the
|
||||
// output, and success will be returned. Otherwise, if a binary value is
|
||||
// encountered, failure will be returned.
|
||||
///
|
||||
JSON_WRITER_OMIT_BINARY_VALUES = 1 << 0,
|
||||
|
||||
///
|
||||
// This option instructs the writer to write doubles that have no fractional
|
||||
// part as a normal integer (i.e., without using exponential notation
|
||||
// or appending a '.0') as long as the value is within the range of a
|
||||
// 64-bit int.
|
||||
///
|
||||
JSON_WRITER_OMIT_DOUBLE_TYPE_PRESERVATION = 1 << 1,
|
||||
|
||||
///
|
||||
// Return a slightly nicer formatted json string (pads with whitespace to
|
||||
// help with readability).
|
||||
///
|
||||
JSON_WRITER_PRETTY_PRINT = 1 << 2,
|
||||
} cef_json_writer_options_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -257,6 +257,50 @@ inline bool operator!=(const CefSize& a, const CefSize& b) {
|
||||
}
|
||||
|
||||
|
||||
struct CefDraggableRegionTraits {
|
||||
typedef cef_draggable_region_t struct_type;
|
||||
|
||||
static inline void init(struct_type* s) {}
|
||||
static inline void clear(struct_type* s) {}
|
||||
|
||||
static inline void set(const struct_type* src, struct_type* target,
|
||||
bool copy) {
|
||||
*target = *src;
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
// Class representing a draggable region.
|
||||
///
|
||||
class CefDraggableRegion : public CefStructBase<CefDraggableRegionTraits> {
|
||||
public:
|
||||
typedef CefStructBase<CefDraggableRegionTraits> parent;
|
||||
|
||||
CefDraggableRegion() : parent() {}
|
||||
CefDraggableRegion(const cef_draggable_region_t& r) // NOLINT(runtime/explicit)
|
||||
: parent(r) {}
|
||||
CefDraggableRegion(const CefDraggableRegion& r) // NOLINT(runtime/explicit)
|
||||
: parent(r) {}
|
||||
CefDraggableRegion(const CefRect& bounds, bool draggable) : parent() {
|
||||
Set(bounds, draggable);
|
||||
}
|
||||
|
||||
void Set(const CefRect& bounds, bool draggable) {
|
||||
this->bounds = bounds, this->draggable = draggable;
|
||||
}
|
||||
};
|
||||
|
||||
inline bool operator==(const CefDraggableRegion& a,
|
||||
const CefDraggableRegion& b) {
|
||||
return a.bounds == b.bounds && a.draggable == b.draggable;
|
||||
}
|
||||
|
||||
inline bool operator!=(const CefDraggableRegion& a,
|
||||
const CefDraggableRegion& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
|
||||
struct CefScreenInfoTraits {
|
||||
typedef cef_screen_info_t struct_type;
|
||||
|
||||
|
372
include/wrapper/cef_resource_manager.h
Normal file
372
include/wrapper/cef_resource_manager.h
Normal file
@@ -0,0 +1,372 @@
|
||||
// Copyright (c) 2015 Marshall A. Greenblatt. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the name Chromium Embedded
|
||||
// Framework nor the names of its contributors may be used to endorse
|
||||
// or promote products derived from this software without specific prior
|
||||
// written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// ---------------------------------------------------------------------------
|
||||
//
|
||||
// The contents of this file are only available to applications that link
|
||||
// against the libcef_dll_wrapper target.
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_
|
||||
#define CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "include/base/cef_macros.h"
|
||||
#include "include/base/cef_ref_counted.h"
|
||||
#include "include/base/cef_weak_ptr.h"
|
||||
#include "include/cef_request_handler.h"
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
|
||||
///
|
||||
// Class for managing multiple resource providers. For each resource request
|
||||
// providers will be called in order and have the option to (a) handle the
|
||||
// request by returning a CefResourceHandler, (b) pass the request to the next
|
||||
// provider in order, or (c) stop handling the request. See comments on the
|
||||
// Request object for additional usage information. The methods of this class
|
||||
// may be called on any browser process thread unless otherwise indicated.
|
||||
///
|
||||
class CefResourceManager :
|
||||
public base::RefCountedThreadSafe<CefResourceManager, CefDeleteOnIOThread> {
|
||||
public:
|
||||
///
|
||||
// Provides an opportunity to modify |url| before it is passed to a provider.
|
||||
// For example, the implementation could rewrite |url| to include a default
|
||||
// file extension. |url| will be fully qualified and may contain query or
|
||||
// fragment components.
|
||||
///
|
||||
typedef base::Callback<std::string(
|
||||
const std::string& /*url*/)> UrlFilter;
|
||||
|
||||
///
|
||||
// Used to resolve mime types for URLs, usually based on the file extension.
|
||||
// |url| will be fully qualified and may contain query or fragment components.
|
||||
///
|
||||
typedef base::Callback<std::string(
|
||||
const std::string& /*url*/)> MimeTypeResolver;
|
||||
|
||||
private:
|
||||
// Values that stay with a request as it moves between providers.
|
||||
struct RequestParams {
|
||||
std::string url_;
|
||||
CefRefPtr<CefBrowser> browser_;
|
||||
CefRefPtr<CefFrame> frame_;
|
||||
CefRefPtr<CefRequest> request_;
|
||||
UrlFilter url_filter_;
|
||||
MimeTypeResolver mime_type_resolver_;
|
||||
};
|
||||
|
||||
// Values that are associated with the pending request only.
|
||||
struct RequestState;
|
||||
|
||||
public:
|
||||
///
|
||||
// Object representing a request. Each request object is used for a single
|
||||
// call to Provider::OnRequest and will become detached (meaning the callbacks
|
||||
// will no longer trigger) after Request::Continue or Request::Stop is called.
|
||||
// A request passed to Provider::OnRequestCanceled will already have been
|
||||
// detached. The methods of this class may be called on any browser process
|
||||
// thread.
|
||||
///
|
||||
class Request : public base::RefCountedThreadSafe<Request> {
|
||||
public:
|
||||
///
|
||||
// Returns the URL associated with this request. The returned value will be
|
||||
// fully qualified but will not contain query or fragment components. It
|
||||
// will already have been passed through the URL filter.
|
||||
///
|
||||
std::string url() const { return params_.url_; }
|
||||
|
||||
///
|
||||
// Returns the CefBrowser associated with this request.
|
||||
///
|
||||
CefRefPtr<CefBrowser> browser() const { return params_.browser_; }
|
||||
|
||||
///
|
||||
// Returns the CefFrame associated with this request.
|
||||
///
|
||||
CefRefPtr<CefFrame> frame() const { return params_.frame_; }
|
||||
|
||||
///
|
||||
// Returns the CefRequest associated with this request.
|
||||
///
|
||||
CefRefPtr<CefRequest> request() const { return params_.request_; }
|
||||
|
||||
///
|
||||
// Returns the current URL filter.
|
||||
///
|
||||
const CefResourceManager::UrlFilter& url_filter() const {
|
||||
return params_.url_filter_;
|
||||
}
|
||||
|
||||
///
|
||||
// Returns the current mime type resolver.
|
||||
///
|
||||
const CefResourceManager::MimeTypeResolver& mime_type_resolver() const {
|
||||
return params_.mime_type_resolver_;
|
||||
}
|
||||
|
||||
///
|
||||
// Continue handling the request. If |handler| is non-NULL then no
|
||||
// additional providers will be called and the |handler| value will be
|
||||
// returned via CefResourceManager::GetResourceHandler. If |handler| is NULL
|
||||
// then the next provider in order, if any, will be called. If there are no
|
||||
// additional providers then NULL will be returned via CefResourceManager::
|
||||
// GetResourceHandler.
|
||||
///
|
||||
void Continue(CefRefPtr<CefResourceHandler> handler);
|
||||
|
||||
///
|
||||
// Stop handling the request. No additional providers will be called and
|
||||
// NULL will be returned via CefResourceManager::GetResourceHandler.
|
||||
///
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
// Only allow deletion via scoped_refptr.
|
||||
friend class base::RefCountedThreadSafe<Request>;
|
||||
|
||||
friend class CefResourceManager;
|
||||
|
||||
// The below methods are called on the browser process IO thread.
|
||||
|
||||
explicit Request(scoped_ptr<RequestState> state);
|
||||
|
||||
scoped_ptr<RequestState> SendRequest();
|
||||
bool HasState();
|
||||
|
||||
static void ContinueOnIOThread(scoped_ptr<RequestState> state,
|
||||
CefRefPtr<CefResourceHandler> handler);
|
||||
static void StopOnIOThread(scoped_ptr<RequestState> state);
|
||||
|
||||
// Will be non-NULL while the request is pending. Only accessed on the
|
||||
// browser process IO thread.
|
||||
scoped_ptr<RequestState> state_;
|
||||
|
||||
// Params that stay with this request object. Safe to access on any thread.
|
||||
RequestParams params_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Request);
|
||||
};
|
||||
|
||||
typedef std::list<scoped_refptr<Request> > RequestList;
|
||||
|
||||
|
||||
///
|
||||
// Interface implemented by resource providers. A provider may be created on
|
||||
// any thread but the methods will be called on, and the object will be
|
||||
// destroyed on, the browser process IO thread.
|
||||
///
|
||||
class Provider {
|
||||
public:
|
||||
///
|
||||
// Called to handle a request. If the provider knows immediately that it
|
||||
// will not handle the request return false. Otherwise, return true and call
|
||||
// Request::Continue or Request::Stop either in this method or
|
||||
// asynchronously to indicate completion. See comments on Request for
|
||||
// additional usage information.
|
||||
///
|
||||
virtual bool OnRequest(scoped_refptr<Request> request) =0;
|
||||
|
||||
///
|
||||
// Called when a request has been canceled. It is still safe to dereference
|
||||
// |request| but any calls to Request::Continue or Request::Stop will be
|
||||
// ignored.
|
||||
///
|
||||
virtual void OnRequestCanceled(scoped_refptr<Request> request) {}
|
||||
|
||||
virtual ~Provider() {}
|
||||
};
|
||||
|
||||
CefResourceManager();
|
||||
|
||||
///
|
||||
// Add a provider that maps requests for |url| to |content|. |url| should be
|
||||
// fully qualified but not include a query or fragment component. If
|
||||
// |mime_type| is empty the MimeTypeResolver will be used. See comments on
|
||||
// AddProvider for usage of the |order| and |identifier| parameters.
|
||||
///
|
||||
void AddContentProvider(const std::string& url,
|
||||
const std::string& content,
|
||||
const std::string& mime_type,
|
||||
int order,
|
||||
const std::string& identifier);
|
||||
|
||||
///
|
||||
// Add a provider that maps requests that start with |url_path| to files under
|
||||
// |directory_path|. |url_path| should include an origin and optional path
|
||||
// component only. Files will be loaded when a matching URL is requested.
|
||||
// See comments on AddProvider for usage of the |order| and |identifier|
|
||||
// parameters.
|
||||
///
|
||||
void AddDirectoryProvider(const std::string& url_path,
|
||||
const std::string& directory_path,
|
||||
int order,
|
||||
const std::string& identifier);
|
||||
|
||||
///
|
||||
// Add a provider that maps requests that start with |url_path| to files
|
||||
// stored in the archive file at |archive_path|. |url_path| should include an
|
||||
// origin and optional path component only. The archive file will be loaded
|
||||
// when a matching URL is requested for the first time. See comments on
|
||||
// AddProvider for usage of the |order| and |identifier| parameters.
|
||||
///
|
||||
void AddArchiveProvider(const std::string& url_path,
|
||||
const std::string& archive_path,
|
||||
const std::string& password,
|
||||
int order,
|
||||
const std::string& identifier);
|
||||
|
||||
///
|
||||
// Add a provider. This object takes ownership of |provider|. Providers will
|
||||
// be called in ascending order based on the |order| value. Multiple providers
|
||||
// sharing the same |order| value will be called in the order that they were
|
||||
// added. The |identifier| value, which does not need to be unique, can be
|
||||
// used to remove the provider at a later time.
|
||||
///
|
||||
void AddProvider(Provider* provider,
|
||||
int order,
|
||||
const std::string& identifier);
|
||||
|
||||
///
|
||||
// Remove all providers with the specified |identifier| value. If any removed
|
||||
// providers have pending requests the Provider::OnRequestCancel method will
|
||||
// be called. The removed providers may be deleted immediately or at a later
|
||||
// time.
|
||||
///
|
||||
void RemoveProviders(const std::string& identifier);
|
||||
|
||||
///
|
||||
// Remove all providers. If any removed providers have pending requests the
|
||||
// Provider::OnRequestCancel method will be called. The removed providers may
|
||||
// be deleted immediately or at a later time.
|
||||
///
|
||||
void RemoveAllProviders();
|
||||
|
||||
///
|
||||
// Set the url filter. If not set the default no-op filter will be used.
|
||||
// Changes to this value will not affect currently pending requests.
|
||||
///
|
||||
void SetUrlFilter(const UrlFilter& filter);
|
||||
|
||||
///
|
||||
// Set the mime type resolver. If not set the default resolver will be used.
|
||||
// Changes to this value will not affect currently pending requests.
|
||||
///
|
||||
void SetMimeTypeResolver(const MimeTypeResolver& resolver);
|
||||
|
||||
|
||||
// The below methods should be called from other CEF handlers. They must be
|
||||
// called exactly as documented for the manager to function correctly.
|
||||
|
||||
///
|
||||
// Called from CefRequestHandler::OnBeforeResourceLoad on the browser process
|
||||
// IO thread.
|
||||
///
|
||||
cef_return_value_t OnBeforeResourceLoad(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefRequestCallback> callback);
|
||||
|
||||
///
|
||||
// Called from CefRequestHandler::GetResourceHandler on the browser process
|
||||
// IO thread.
|
||||
///
|
||||
CefRefPtr<CefResourceHandler> GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request);
|
||||
|
||||
private:
|
||||
// Only allow deletion via scoped_refptr.
|
||||
friend struct CefDeleteOnThread<TID_IO>;
|
||||
friend class base::RefCountedThreadSafe<CefResourceManager,
|
||||
CefDeleteOnIOThread>;
|
||||
|
||||
~CefResourceManager();
|
||||
|
||||
// Provider and associated information.
|
||||
struct ProviderEntry;
|
||||
typedef std::list<ProviderEntry*> ProviderEntryList;
|
||||
|
||||
// Values associated with the pending request only. Ownership will be passed
|
||||
// between requests and the resource manager as request handling proceeds.
|
||||
struct RequestState {
|
||||
~RequestState();
|
||||
|
||||
base::WeakPtr<CefResourceManager> manager_;
|
||||
|
||||
// Callback to execute once request handling is complete.
|
||||
CefRefPtr<CefRequestCallback> callback_;
|
||||
|
||||
// Position of the currently associated ProviderEntry in the |providers_|
|
||||
// list.
|
||||
ProviderEntryList::iterator current_entry_pos_;
|
||||
|
||||
// Position of this request object in the currently associated
|
||||
// ProviderEntry's |pending_requests_| list.
|
||||
RequestList::iterator current_request_pos_;
|
||||
|
||||
// Params that will be copied to each request object.
|
||||
RequestParams params_;
|
||||
};
|
||||
|
||||
// Methods that manage request state between requests. Called on the browser
|
||||
// process IO thread.
|
||||
bool SendRequest(scoped_ptr<RequestState> state);
|
||||
void ContinueRequest(scoped_ptr<RequestState> state,
|
||||
CefRefPtr<CefResourceHandler> handler);
|
||||
void StopRequest(scoped_ptr<RequestState> state);
|
||||
bool IncrementProvider(RequestState* state);
|
||||
void DetachRequestFromProvider(RequestState* state);
|
||||
void GetNextValidProvider(ProviderEntryList::iterator& iterator);
|
||||
void DeleteProvider(ProviderEntryList::iterator& iterator, bool stop);
|
||||
|
||||
// The below members are only accessed on the browser process IO thread.
|
||||
|
||||
// List of providers including additional associated information.
|
||||
ProviderEntryList providers_;
|
||||
|
||||
// Map of response ID to pending CefResourceHandler object.
|
||||
typedef std::map<uint64, CefRefPtr<CefResourceHandler> > PendingHandlersMap;
|
||||
PendingHandlersMap pending_handlers_;
|
||||
|
||||
UrlFilter url_filter_;
|
||||
MimeTypeResolver mime_type_resolver_;
|
||||
|
||||
// Must be the last member.
|
||||
base::WeakPtrFactory<CefResourceManager> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefResourceManager);
|
||||
};
|
||||
|
||||
#endif // CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_
|
@@ -10,6 +10,7 @@
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/download_manager_delegate.h"
|
||||
#include "libcef/browser/permission_manager.h"
|
||||
#include "libcef/browser/ssl_host_state_delegate.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
|
||||
#include "base/files/file_util.h"
|
||||
@@ -195,7 +196,9 @@ content::PushMessagingService*
|
||||
|
||||
content::SSLHostStateDelegate*
|
||||
CefBrowserContextImpl::GetSSLHostStateDelegate() {
|
||||
return NULL;
|
||||
if (!ssl_host_state_delegate_.get())
|
||||
ssl_host_state_delegate_.reset(new CefSSLHostStateDelegate());
|
||||
return ssl_host_state_delegate_.get();
|
||||
}
|
||||
|
||||
content::PermissionManager* CefBrowserContextImpl::GetPermissionManager() {
|
||||
|
@@ -21,6 +21,7 @@ class SpeechRecognitionPreferences;
|
||||
}
|
||||
|
||||
class CefDownloadManagerDelegate;
|
||||
class CefSSLHostStateDelegate;
|
||||
|
||||
// Isolated BrowserContext implementation. Life span is controlled by
|
||||
// CefRequestContextImpl and (for the main context) CefBrowserMainParts. Only
|
||||
@@ -97,6 +98,7 @@ class CefBrowserContextImpl : public CefBrowserContext {
|
||||
scoped_ptr<CefDownloadManagerDelegate> download_manager_delegate_;
|
||||
scoped_refptr<CefURLRequestContextGetterImpl> url_request_getter_;
|
||||
scoped_ptr<content::PermissionManager> permission_manager_;
|
||||
scoped_ptr<CefSSLHostStateDelegate> ssl_host_state_delegate_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefBrowserContextImpl);
|
||||
};
|
||||
|
@@ -2633,6 +2633,8 @@ bool CefBrowserHostImpl::OnMessageReceived(const IPC::Message& message) {
|
||||
IPC_BEGIN_MESSAGE_MAP(CefBrowserHostImpl, message)
|
||||
IPC_MESSAGE_HANDLER(CefHostMsg_FrameIdentified, OnFrameIdentified)
|
||||
IPC_MESSAGE_HANDLER(CefHostMsg_DidFinishLoad, OnDidFinishLoad)
|
||||
IPC_MESSAGE_HANDLER(CefHostMsg_UpdateDraggableRegions,
|
||||
OnUpdateDraggableRegions)
|
||||
IPC_MESSAGE_HANDLER(CefHostMsg_Request, OnRequest)
|
||||
IPC_MESSAGE_HANDLER(CefHostMsg_Response, OnResponse)
|
||||
IPC_MESSAGE_HANDLER(CefHostMsg_ResponseAck, OnResponseAck)
|
||||
@@ -2682,6 +2684,26 @@ void CefBrowserHostImpl::OnDidFinishLoad(int64 frame_id,
|
||||
OnLoadEnd(frame, validated_url, http_status_code);
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::OnUpdateDraggableRegions(
|
||||
const std::vector<Cef_DraggableRegion_Params>& regions) {
|
||||
std::vector<CefDraggableRegion> draggable_regions;
|
||||
draggable_regions.reserve(regions.size());
|
||||
|
||||
std::vector<Cef_DraggableRegion_Params>::const_iterator it = regions.begin();
|
||||
for (; it != regions.end(); ++it) {
|
||||
const gfx::Rect& rect(it->bounds);
|
||||
const CefRect bounds(rect.x(), rect.y(), rect.width(), rect.height());
|
||||
draggable_regions.push_back(CefDraggableRegion(bounds, it->draggable));
|
||||
}
|
||||
|
||||
if (client_.get()) {
|
||||
CefRefPtr<CefDragHandler> handler = client_->GetDragHandler();
|
||||
if (handler.get()) {
|
||||
handler->OnDraggableRegionsChanged(this, draggable_regions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::OnRequest(const Cef_Request_Params& params) {
|
||||
bool success = false;
|
||||
std::string response;
|
||||
|
@@ -64,6 +64,7 @@ class Widget;
|
||||
class CefWindowX11;
|
||||
#endif
|
||||
|
||||
struct Cef_DraggableRegion_Params;
|
||||
struct Cef_Request_Params;
|
||||
struct Cef_Response_Params;
|
||||
class CefBrowserInfo;
|
||||
@@ -475,6 +476,8 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
const GURL& validated_url,
|
||||
bool is_main_frame,
|
||||
int http_status_code);
|
||||
void OnUpdateDraggableRegions(
|
||||
const std::vector<Cef_DraggableRegion_Params>& regions);
|
||||
void OnRequest(const Cef_Request_Params& params);
|
||||
void OnResponse(const Cef_Response_Params& params);
|
||||
void OnResponseAck(int request_id);
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "ui/aura/window_tree_host.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
#include "ui/gfx/win/hwnd_util.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
@@ -511,6 +512,9 @@ bool RunSaveFileDialog(const CefBrowserHostImpl::FileChooserParams& params,
|
||||
ofn.lpstrFilter = filter.c_str();
|
||||
// Indices into |lpstrFilter| start at 1.
|
||||
ofn.nFilterIndex = *filter_index + 1;
|
||||
// If a filter is specified and the default file name is changed then append
|
||||
// a file extension to the new name.
|
||||
ofn.lpstrDefExt = L"";
|
||||
}
|
||||
|
||||
bool success = !!GetSaveFileName(&ofn);
|
||||
@@ -806,11 +810,17 @@ bool CefBrowserHostImpl::PlatformCreateWindow() {
|
||||
CefColorGetB(settings.background_color));
|
||||
}
|
||||
|
||||
// Adjust for potential display scaling.
|
||||
gfx::Point point = gfx::Point(cr.right, cr.bottom);
|
||||
float scale = gfx::Screen::GetNativeScreen()->
|
||||
GetDisplayNearestPoint(point).device_scale_factor();
|
||||
point = gfx::ToFlooredPoint(gfx::ScalePoint(point, 1.0f / scale));
|
||||
|
||||
CefWindowDelegateView* delegate_view =
|
||||
new CefWindowDelegateView(background_color);
|
||||
delegate_view->Init(window_info_.window,
|
||||
web_contents(),
|
||||
gfx::Rect(0, 0, cr.right, cr.bottom));
|
||||
gfx::Rect(0, 0, point.x(), point.y()));
|
||||
|
||||
window_widget_ = delegate_view->GetWidget();
|
||||
window_widget_->Show();
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "content/public/browser/access_token_store.h"
|
||||
#include "content/public/browser/browser_url_handler.h"
|
||||
#include "content/public/browser/child_process_security_policy.h"
|
||||
#include "content/public/browser/client_certificate_delegate.h"
|
||||
#include "content/public/browser/plugin_service_filter.h"
|
||||
#include "content/public/browser/quota_permission_context.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
@@ -45,6 +46,8 @@
|
||||
#include "content/public/common/content_switches.h"
|
||||
#include "content/public/common/storage_quota_params.h"
|
||||
#include "content/public/common/web_preferences.h"
|
||||
#include "gin/public/isolate_holder.h"
|
||||
#include "net/ssl/ssl_cert_request_info.h"
|
||||
#include "third_party/WebKit/public/web/WebWindowFeatures.h"
|
||||
#include "ui/base/ui_base_switches.h"
|
||||
#include "url/gurl.h"
|
||||
@@ -187,7 +190,7 @@ class CefAllowCertificateErrorCallbackImpl : public CefRequestCallback {
|
||||
|
||||
private:
|
||||
static void RunNow(const CallbackType& callback, bool allow) {
|
||||
CEF_REQUIRE_IOT();
|
||||
CEF_REQUIRE_UIT();
|
||||
callback.Run(allow);
|
||||
}
|
||||
|
||||
@@ -381,6 +384,10 @@ int GetCrashSignalFD(const base::CommandLine& command_line) {
|
||||
|
||||
CefContentBrowserClient::CefContentBrowserClient()
|
||||
: browser_main_parts_(NULL),
|
||||
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
||||
v8_natives_fd_(-1),
|
||||
v8_snapshot_fd_(-1),
|
||||
#endif // OS_POSIX && !OS_MACOSX
|
||||
next_browser_id_(0) {
|
||||
plugin_service_filter_.reset(new CefPluginServiceFilter);
|
||||
content::PluginServiceImpl::GetInstance()->SetFilter(
|
||||
@@ -745,6 +752,16 @@ void CefContentBrowserClient::AllowCertificateError(
|
||||
content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL;
|
||||
}
|
||||
|
||||
void CefContentBrowserClient::SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) {
|
||||
if (!cert_request_info->client_certs.empty()) {
|
||||
// Use the first certificate.
|
||||
delegate->ContinueWithCertificate(cert_request_info->client_certs[0].get());
|
||||
}
|
||||
}
|
||||
|
||||
content::AccessTokenStore* CefContentBrowserClient::CreateAccessTokenStore() {
|
||||
return new CefAccessTokenStore(
|
||||
browser_main_parts_->browser_context()->request_context().get());
|
||||
@@ -866,7 +883,8 @@ void CefContentBrowserClient::OverrideWebkitPrefs(
|
||||
BrowserToWebSettings(browser->settings(), *prefs);
|
||||
|
||||
prefs->base_background_color = GetBaseBackgroundColor(rvh);
|
||||
rvh->GetView()->SetBackgroundColor(prefs->base_background_color);
|
||||
if (rvh->GetView())
|
||||
rvh->GetView()->SetBackgroundColor(prefs->base_background_color);
|
||||
|
||||
prefs->asynchronous_spell_checking_enabled = true;
|
||||
// Auto-correct does not work in combination with the unified text checker.
|
||||
@@ -902,6 +920,28 @@ void CefContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
|
||||
const base::CommandLine& command_line,
|
||||
int child_process_id,
|
||||
content::FileDescriptorInfo* mappings) {
|
||||
#if defined(V8_USE_EXTERNAL_STARTUP_DATA)
|
||||
if (v8_snapshot_fd_.get() == -1 && v8_natives_fd_.get() == -1) {
|
||||
base::FilePath v8_data_path;
|
||||
PathService::Get(gin::IsolateHolder::kV8SnapshotBasePathKey, &v8_data_path);
|
||||
DCHECK(!v8_data_path.empty());
|
||||
|
||||
int file_flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
|
||||
base::FilePath v8_natives_data_path =
|
||||
v8_data_path.AppendASCII(gin::IsolateHolder::kNativesFileName);
|
||||
base::FilePath v8_snapshot_data_path =
|
||||
v8_data_path.AppendASCII(gin::IsolateHolder::kSnapshotFileName);
|
||||
base::File v8_natives_data_file(v8_natives_data_path, file_flags);
|
||||
base::File v8_snapshot_data_file(v8_snapshot_data_path, file_flags);
|
||||
DCHECK(v8_natives_data_file.IsValid());
|
||||
DCHECK(v8_snapshot_data_file.IsValid());
|
||||
v8_natives_fd_.reset(v8_natives_data_file.TakePlatformFile());
|
||||
v8_snapshot_fd_.reset(v8_snapshot_data_file.TakePlatformFile());
|
||||
}
|
||||
mappings->Share(kV8NativesDataDescriptor, v8_natives_fd_.get());
|
||||
mappings->Share(kV8SnapshotDataDescriptor, v8_snapshot_fd_.get());
|
||||
#endif // V8_USE_EXTERNAL_STARTUP_DATA
|
||||
|
||||
int crash_signal_fd = GetCrashSignalFD(command_line);
|
||||
if (crash_signal_fd >= 0) {
|
||||
mappings->Share(kCrashDumpSignal, crash_signal_fd);
|
||||
|
@@ -105,6 +105,10 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
|
||||
bool expired_previous_decision,
|
||||
const base::Callback<void(bool)>& callback,
|
||||
content::CertificateRequestResultType* result) override;
|
||||
void SelectClientCertificate(
|
||||
content::WebContents* web_contents,
|
||||
net::SSLCertRequestInfo* cert_request_info,
|
||||
scoped_ptr<content::ClientCertificateDelegate> delegate) override;
|
||||
content::AccessTokenStore* CreateAccessTokenStore() override;
|
||||
bool CanCreateWindow(const GURL& opener_url,
|
||||
const GURL& opener_top_level_frame_url,
|
||||
@@ -168,6 +172,11 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
|
||||
scoped_ptr<CefResourceDispatcherHostDelegate>
|
||||
resource_dispatcher_host_delegate_;
|
||||
|
||||
#if defined(OS_POSIX) && !defined(OS_MACOSX)
|
||||
base::ScopedFD v8_natives_fd_;
|
||||
base::ScopedFD v8_snapshot_fd_;
|
||||
#endif
|
||||
|
||||
base::Lock browser_info_lock_;
|
||||
|
||||
// Access must be protected by |browser_info_lock_|.
|
||||
|
@@ -208,7 +208,7 @@ void CefJavaScriptDialogManager::CancelActiveAndPendingDialogs(
|
||||
#endif
|
||||
}
|
||||
|
||||
void CefJavaScriptDialogManager::WebContentsDestroyed(
|
||||
void CefJavaScriptDialogManager::ResetDialogState(
|
||||
content::WebContents* web_contents) {
|
||||
}
|
||||
|
||||
|
@@ -41,7 +41,7 @@ class CefJavaScriptDialogManager : public content::JavaScriptDialogManager {
|
||||
void CancelActiveAndPendingDialogs(
|
||||
content::WebContents* web_contents) override;
|
||||
|
||||
void WebContentsDestroyed(
|
||||
void ResetDialogState(
|
||||
content::WebContents* web_contents) override;
|
||||
|
||||
// Called by the CefJavaScriptDialog when it closes.
|
||||
|
@@ -8,6 +8,8 @@
|
||||
#include "base/message_loop/message_loop.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
#include "ui/gfx/geometry/point_conversions.h"
|
||||
#include "ui/gfx/screen.h"
|
||||
#include "ui/views/controls/menu/menu_2.h"
|
||||
|
||||
CefMenuCreatorRunnerWin::CefMenuCreatorRunnerWin() {
|
||||
@@ -46,6 +48,11 @@ bool CefMenuCreatorRunnerWin::RunContextMenu(CefMenuCreator* manager) {
|
||||
const gfx::Rect& bounds_in_screen = window->GetBoundsInScreen();
|
||||
screen_point = gfx::Point(bounds_in_screen.x() + manager->params().x,
|
||||
bounds_in_screen.y() + manager->params().y);
|
||||
|
||||
// Adjust for potential display scaling.
|
||||
float scale = gfx::Screen::GetScreenFor(window)->
|
||||
GetDisplayNearestWindow(window).device_scale_factor();
|
||||
screen_point = gfx::ToFlooredPoint(gfx::ScalePoint(screen_point, scale));
|
||||
}
|
||||
|
||||
// Show the menu. Blocks until the menu is dismissed.
|
||||
|
@@ -8,6 +8,18 @@
|
||||
#include "base/logging.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
|
||||
#if defined(USE_NSS)
|
||||
#include "net/ssl/client_cert_store_nss.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "net/ssl/client_cert_store_win.h"
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#include "net/ssl/client_cert_store_mac.h"
|
||||
#endif
|
||||
|
||||
CefResourceContext::CefResourceContext() {
|
||||
}
|
||||
|
||||
@@ -35,6 +47,24 @@ net::URLRequestContext* CefResourceContext::GetRequestContext() {
|
||||
return getter_->GetURLRequestContext();
|
||||
}
|
||||
|
||||
scoped_ptr<net::ClientCertStore> CefResourceContext::CreateClientCertStore() {
|
||||
#if defined(USE_NSS)
|
||||
return scoped_ptr<net::ClientCertStore>(new net::ClientCertStoreNSS(
|
||||
net::ClientCertStoreNSS::PasswordDelegateFactory()));
|
||||
#elif defined(OS_WIN)
|
||||
return scoped_ptr<net::ClientCertStore>(new net::ClientCertStoreWin());
|
||||
#elif defined(OS_MACOSX)
|
||||
return scoped_ptr<net::ClientCertStore>(new net::ClientCertStoreMac());
|
||||
#elif defined(USE_OPENSSL)
|
||||
// OpenSSL does not use the ClientCertStore infrastructure. On Android client
|
||||
// cert matching is done by the OS as part of the call to show the cert
|
||||
// selection dialog.
|
||||
return scoped_ptr<net::ClientCertStore>();
|
||||
#else
|
||||
#error Unknown platform.
|
||||
#endif
|
||||
}
|
||||
|
||||
void CefResourceContext::set_url_request_context_getter(
|
||||
scoped_refptr<CefURLRequestContextGetter> getter) {
|
||||
DCHECK(!getter_.get());
|
||||
|
@@ -26,6 +26,7 @@ class CefResourceContext : public content::ResourceContext {
|
||||
// ResourceContext implementation.
|
||||
net::HostResolver* GetHostResolver() override;
|
||||
net::URLRequestContext* GetRequestContext() override;
|
||||
scoped_ptr<net::ClientCertStore> CreateClientCertStore() override;
|
||||
|
||||
void set_url_request_context_getter(
|
||||
scoped_refptr<CefURLRequestContextGetter> getter);
|
||||
|
86
libcef/browser/ssl_host_state_delegate.cc
Normal file
86
libcef/browser/ssl_host_state_delegate.cc
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "libcef/browser/ssl_host_state_delegate.h"
|
||||
|
||||
#include "net/base/hash_value.h"
|
||||
|
||||
using content::SSLHostStateDelegate;
|
||||
|
||||
namespace internal {
|
||||
|
||||
net::SHA256HashValue getChainFingerprint256(const net::X509Certificate& cert) {
|
||||
net::SHA256HashValue fingerprint =
|
||||
net::X509Certificate::CalculateChainFingerprint256(
|
||||
cert.os_cert_handle(), cert.GetIntermediateCertificates());
|
||||
return fingerprint;
|
||||
}
|
||||
|
||||
CertPolicy::CertPolicy() {
|
||||
}
|
||||
CertPolicy::~CertPolicy() {
|
||||
}
|
||||
|
||||
// For an allowance, we consider a given |cert| to be a match to a saved
|
||||
// allowed cert if the |error| is an exact match to or subset of the errors
|
||||
// in the saved CertStatus.
|
||||
bool CertPolicy::Check(const net::X509Certificate& cert,
|
||||
net::CertStatus error) const {
|
||||
net::SHA256HashValue fingerprint = getChainFingerprint256(cert);
|
||||
std::map<net::SHA256HashValue, net::CertStatus,
|
||||
net::SHA256HashValueLessThan>::const_iterator allowed_iter =
|
||||
allowed_.find(fingerprint);
|
||||
if ((allowed_iter != allowed_.end()) && (allowed_iter->second & error) &&
|
||||
((allowed_iter->second & error) == error)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CertPolicy::Allow(const net::X509Certificate& cert,
|
||||
net::CertStatus error) {
|
||||
// If this same cert had already been saved with a different error status,
|
||||
// this will replace it with the new error status.
|
||||
net::SHA256HashValue fingerprint = getChainFingerprint256(cert);
|
||||
allowed_[fingerprint] = error;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
CefSSLHostStateDelegate::CefSSLHostStateDelegate() {
|
||||
}
|
||||
|
||||
CefSSLHostStateDelegate::~CefSSLHostStateDelegate() {
|
||||
}
|
||||
|
||||
void CefSSLHostStateDelegate::HostRanInsecureContent(const std::string& host,
|
||||
int pid) {
|
||||
// Intentional no-op.
|
||||
}
|
||||
|
||||
bool CefSSLHostStateDelegate::DidHostRunInsecureContent(const std::string& host,
|
||||
int pid) const {
|
||||
// Intentional no-op.
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefSSLHostStateDelegate::AllowCert(const std::string& host,
|
||||
const net::X509Certificate& cert,
|
||||
net::CertStatus error) {
|
||||
cert_policy_for_host_[host].Allow(cert, error);
|
||||
}
|
||||
|
||||
void CefSSLHostStateDelegate::Clear() {
|
||||
cert_policy_for_host_.clear();
|
||||
}
|
||||
|
||||
SSLHostStateDelegate::CertJudgment CefSSLHostStateDelegate::QueryPolicy(
|
||||
const std::string& host,
|
||||
const net::X509Certificate& cert,
|
||||
net::CertStatus error,
|
||||
bool* expired_previous_decision) {
|
||||
return cert_policy_for_host_[host].Check(cert, error)
|
||||
? SSLHostStateDelegate::ALLOWED
|
||||
: SSLHostStateDelegate::DENIED;
|
||||
}
|
74
libcef/browser/ssl_host_state_delegate.h
Normal file
74
libcef/browser/ssl_host_state_delegate.h
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_LIBCEF_BROWSER_SSL_HOST_STATE_DELEGATE_H_
|
||||
#define CEF_LIBCEF_BROWSER_SSL_HOST_STATE_DELEGATE_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "content/public/browser/ssl_host_state_delegate.h"
|
||||
#include "net/base/hash_value.h"
|
||||
#include "net/cert/cert_status_flags.h"
|
||||
#include "net/cert/x509_certificate.h"
|
||||
|
||||
namespace internal {
|
||||
|
||||
// This class maintains the policy for storing actions on certificate errors.
|
||||
class CertPolicy {
|
||||
public:
|
||||
CertPolicy();
|
||||
~CertPolicy();
|
||||
// Returns true if the user has decided to proceed through the ssl error
|
||||
// before. For a certificate to be allowed, it must not have any
|
||||
// *additional* errors from when it was allowed.
|
||||
bool Check(const net::X509Certificate& cert, net::CertStatus error) const;
|
||||
|
||||
// Causes the policy to allow this certificate for a given |error|. And
|
||||
// remember the user's choice.
|
||||
void Allow(const net::X509Certificate& cert, net::CertStatus error);
|
||||
|
||||
private:
|
||||
// The set of fingerprints of allowed certificates.
|
||||
std::map<net::SHA256HashValue, net::CertStatus, net::SHA256HashValueLessThan>
|
||||
allowed_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
class CefSSLHostStateDelegate : public content::SSLHostStateDelegate {
|
||||
public:
|
||||
CefSSLHostStateDelegate();
|
||||
~CefSSLHostStateDelegate() override;
|
||||
|
||||
// Records that |cert| is permitted to be used for |host| in the future, for
|
||||
// a specified |error| type.
|
||||
void AllowCert(const std::string& host,
|
||||
const net::X509Certificate& cert,
|
||||
net::CertStatus error) override;
|
||||
|
||||
void Clear() override;
|
||||
|
||||
// Queries whether |cert| is allowed or denied for |host| and |error|.
|
||||
content::SSLHostStateDelegate::CertJudgment QueryPolicy(
|
||||
const std::string& host,
|
||||
const net::X509Certificate& cert,
|
||||
net::CertStatus error,
|
||||
bool* expired_previous_decision) override;
|
||||
|
||||
// Records that a host has run insecure content.
|
||||
void HostRanInsecureContent(const std::string& host, int pid) override;
|
||||
|
||||
// Returns whether the specified host ran insecure content.
|
||||
bool DidHostRunInsecureContent(const std::string& host,
|
||||
int pid) const override;
|
||||
|
||||
private:
|
||||
// Certificate policies for each host.
|
||||
std::map<std::string, internal::CertPolicy> cert_policy_for_host_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CefSSLHostStateDelegate);
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_SSL_HOST_STATE_DELEGATE_H_
|
@@ -1,6 +1,13 @@
|
||||
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that can
|
||||
// be found in the LICENSE file.
|
||||
// Copyright 2014 The Chromium Embedded Framework Authors. Portions copyright
|
||||
// 2011 the Chromium Authors. All rights reserved. Use of this source code is
|
||||
// governed by a BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
#include "include/base/cef_build.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <windows.h>
|
||||
#include <shellscalingapi.h>
|
||||
#endif
|
||||
|
||||
#include "include/internal/cef_trace_event_internal.h"
|
||||
#include "include/internal/cef_logging_internal.h"
|
||||
@@ -10,6 +17,55 @@
|
||||
#include "base/threading/platform_thread.h"
|
||||
#include "base/trace_event/trace_event.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/win/windows_version.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Implementation from chrome/app/chrome_exe_main_win.cc.
|
||||
|
||||
// Win8.1 supports monitor-specific DPI scaling.
|
||||
bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
|
||||
typedef HRESULT(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS);
|
||||
SetProcessDpiAwarenessPtr set_process_dpi_awareness_func =
|
||||
reinterpret_cast<SetProcessDpiAwarenessPtr>(
|
||||
GetProcAddress(GetModuleHandleA("user32.dll"),
|
||||
"SetProcessDpiAwarenessInternal"));
|
||||
if (set_process_dpi_awareness_func) {
|
||||
HRESULT hr = set_process_dpi_awareness_func(value);
|
||||
if (SUCCEEDED(hr)) {
|
||||
VLOG(1) << "SetProcessDpiAwareness succeeded.";
|
||||
return true;
|
||||
} else if (hr == E_ACCESSDENIED) {
|
||||
LOG(ERROR) << "Access denied error from SetProcessDpiAwareness. "
|
||||
"Function called twice, or manifest was used.";
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function works for Windows Vista through Win8. Win8.1 must use
|
||||
// SetProcessDpiAwareness[Wrapper].
|
||||
BOOL SetProcessDPIAwareWrapper() {
|
||||
typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
|
||||
SetProcessDPIAwarePtr set_process_dpi_aware_func =
|
||||
reinterpret_cast<SetProcessDPIAwarePtr>(
|
||||
GetProcAddress(GetModuleHandleA("user32.dll"),
|
||||
"SetProcessDPIAware"));
|
||||
return set_process_dpi_aware_func &&
|
||||
set_process_dpi_aware_func();
|
||||
}
|
||||
|
||||
void EnableHighDPISupport() {
|
||||
if (!SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) {
|
||||
SetProcessDPIAwareWrapper();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
// The contents of this file are a compilation unit that is not called by other
|
||||
// functions in the the library. Consiquently MSVS will exclude it during the
|
||||
// linker stage if we don't call a stub function.
|
||||
@@ -343,3 +399,13 @@ CEF_EXPORT cef_platform_thread_handle_t
|
||||
return base::PlatformThread::CurrentHandle().platform_handle();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CefEnableHighDPISupport() {
|
||||
#if defined(OS_WIN)
|
||||
// We don't want to set DPI awareness on pre-Win7 because we don't support
|
||||
// DirectWrite there. GDI fonts are kerned very badly, so better to leave
|
||||
// DPI-unaware and at effective 1.0. See also ShouldUseDirectWrite().
|
||||
if (base::win::GetVersion() >= base::win::VERSION_WIN7)
|
||||
EnableHighDPISupport();
|
||||
#endif
|
||||
}
|
||||
|
@@ -68,6 +68,12 @@ IPC_STRUCT_BEGIN(Cef_CrossOriginWhiteListEntry_Params)
|
||||
IPC_STRUCT_MEMBER(bool, allow_target_subdomains)
|
||||
IPC_STRUCT_END()
|
||||
|
||||
// Parameters structure for a draggable region.
|
||||
IPC_STRUCT_BEGIN(Cef_DraggableRegion_Params)
|
||||
IPC_STRUCT_MEMBER(gfx::Rect, bounds)
|
||||
IPC_STRUCT_MEMBER(bool, draggable)
|
||||
IPC_STRUCT_END()
|
||||
|
||||
|
||||
// Messages sent from the browser to the renderer.
|
||||
|
||||
@@ -189,6 +195,10 @@ IPC_MESSAGE_ROUTED1(CefHostMsg_Response,
|
||||
IPC_MESSAGE_ROUTED1(CefHostMsg_ResponseAck,
|
||||
int /* request_id */)
|
||||
|
||||
// Sent by the renderer when the draggable regions are updated.
|
||||
IPC_MESSAGE_ROUTED1(CefHostMsg_UpdateDraggableRegions,
|
||||
std::vector<Cef_DraggableRegion_Params> /* regions */)
|
||||
|
||||
|
||||
// Singly-included section for struct and custom IPC traits.
|
||||
#ifndef CEF_LIBCEF_COMMON_CEF_MESSAGES_H_
|
||||
|
78
libcef/common/json_impl.cc
Normal file
78
libcef/common/json_impl.cc
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that can
|
||||
// be found in the LICENSE file.
|
||||
|
||||
#include "include/cef_parser.h"
|
||||
#include "libcef/common/values_impl.h"
|
||||
|
||||
#include "base/values.h"
|
||||
#include "base/json/json_reader.h"
|
||||
#include "base/json/json_writer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
int GetJSONReaderOptions(cef_json_parser_options_t options) {
|
||||
int op = base::JSON_PARSE_RFC;
|
||||
if (options & JSON_PARSER_ALLOW_TRAILING_COMMAS)
|
||||
op |= base::JSON_ALLOW_TRAILING_COMMAS;
|
||||
return op;
|
||||
}
|
||||
|
||||
int GetJSONWriterOptions(cef_json_writer_options_t options) {
|
||||
int op = 0;
|
||||
if (op & JSON_WRITER_OMIT_BINARY_VALUES)
|
||||
op |= base::JSONWriter::OPTIONS_OMIT_BINARY_VALUES;
|
||||
if (op & JSON_WRITER_OMIT_DOUBLE_TYPE_PRESERVATION)
|
||||
op |= base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION;
|
||||
if (op & JSON_WRITER_PRETTY_PRINT)
|
||||
op |= base::JSONWriter::OPTIONS_PRETTY_PRINT;
|
||||
return op;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CefRefPtr<CefValue> CefParseJSON(const CefString& json_string,
|
||||
cef_json_parser_options_t options) {
|
||||
const std::string& json = json_string.ToString();
|
||||
base::Value* parse_result =
|
||||
base::JSONReader::Read(json, GetJSONReaderOptions(options));
|
||||
if (parse_result)
|
||||
return new CefValueImpl(parse_result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CefRefPtr<CefValue> CefParseJSONAndReturnError(
|
||||
const CefString& json_string,
|
||||
cef_json_parser_options_t options,
|
||||
cef_json_parser_error_t& error_code_out,
|
||||
CefString& error_msg_out) {
|
||||
const std::string& json = json_string.ToString();
|
||||
|
||||
int error_code;
|
||||
std::string error_msg;
|
||||
base::Value* parse_result = base::JSONReader::ReadAndReturnError(
|
||||
json, GetJSONReaderOptions(options), &error_code, &error_msg);
|
||||
if (parse_result)
|
||||
return new CefValueImpl(parse_result);
|
||||
|
||||
error_code_out = static_cast<cef_json_parser_error_t>(error_code);
|
||||
error_msg_out = error_msg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CefString CefWriteJSON(CefRefPtr<CefValue> node,
|
||||
cef_json_writer_options_t options) {
|
||||
if (!node.get() || !node->IsValid())
|
||||
return CefString();
|
||||
|
||||
CefValueImpl* impl = static_cast<CefValueImpl*>(node.get());
|
||||
CefValueImpl::ScopedLockedValue scoped_value(impl);
|
||||
|
||||
std::string json_string;
|
||||
if (base::JSONWriter::WriteWithOptions(scoped_value.value(),
|
||||
GetJSONWriterOptions(options),
|
||||
&json_string)) {
|
||||
return json_string;
|
||||
}
|
||||
return CefString();
|
||||
}
|
@@ -610,6 +610,7 @@ void CefMainDelegate::InitializeResourceBundle() {
|
||||
resources_dir = GetResourcesFilePath();
|
||||
|
||||
if (!resources_dir.empty()) {
|
||||
CHECK(resources_dir.IsAbsolute());
|
||||
cef_pak_file = resources_dir.Append(FILE_PATH_LITERAL("cef.pak"));
|
||||
cef_100_percent_pak_file =
|
||||
resources_dir.Append(FILE_PATH_LITERAL("cef_100_percent.pak"));
|
||||
|
@@ -71,6 +71,9 @@ class CefValueController
|
||||
// Returns true if the controller is locked on the current thread.
|
||||
virtual bool locked() =0;
|
||||
|
||||
// Assert that the lock has been acquired.
|
||||
virtual void AssertLockAcquired() =0;
|
||||
|
||||
// Verify that the current thread is correct for accessing the controller.
|
||||
inline bool VerifyThread() {
|
||||
if (!thread_safe() && !on_correct_thread()) {
|
||||
@@ -149,6 +152,9 @@ class CefValueControllerThreadSafe : public CefValueController {
|
||||
bool locked() override {
|
||||
return (locked_thread_id_ == base::PlatformThread::CurrentId());
|
||||
}
|
||||
void AssertLockAcquired() override {
|
||||
lock_.AssertAcquired();
|
||||
}
|
||||
|
||||
private:
|
||||
base::Lock lock_;
|
||||
@@ -171,6 +177,9 @@ class CefValueControllerNonThreadSafe : public CefValueController {
|
||||
void lock() override {}
|
||||
void unlock() override {}
|
||||
bool locked() override { return on_correct_thread(); }
|
||||
void AssertLockAcquired() override {
|
||||
DCHECK(locked());
|
||||
}
|
||||
|
||||
private:
|
||||
base::PlatformThreadId thread_id_;
|
||||
|
@@ -363,6 +363,55 @@ void CefValueImpl::SetValueInternal(base::Value* value) {
|
||||
}
|
||||
}
|
||||
|
||||
CefValueController* CefValueImpl::GetValueController() const {
|
||||
lock_.AssertAcquired();
|
||||
|
||||
if (binary_value_) {
|
||||
return static_cast<CefBinaryValueImpl*>(binary_value_.get())->controller();
|
||||
} else if (dictionary_value_) {
|
||||
return static_cast<CefDictionaryValueImpl*>(dictionary_value_.get())->
|
||||
controller();
|
||||
} else if (list_value_) {
|
||||
return static_cast<CefListValueImpl*>(list_value_.get())->controller();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CefValueImpl::AcquireLock() {
|
||||
lock_.Acquire();
|
||||
|
||||
CefValueController* controller = GetValueController();
|
||||
if (controller)
|
||||
controller->lock();
|
||||
}
|
||||
|
||||
void CefValueImpl::ReleaseLock() {
|
||||
CefValueController* controller = GetValueController();
|
||||
if (controller) {
|
||||
controller->AssertLockAcquired();
|
||||
controller->unlock();
|
||||
}
|
||||
|
||||
lock_.Release();
|
||||
}
|
||||
|
||||
base::Value* CefValueImpl::GetValueUnsafe() const {
|
||||
lock_.AssertAcquired();
|
||||
|
||||
if (binary_value_) {
|
||||
return static_cast<CefBinaryValueImpl*>(binary_value_.get())->
|
||||
GetValueUnsafe();
|
||||
} else if (dictionary_value_) {
|
||||
return static_cast<CefDictionaryValueImpl*>(dictionary_value_.get())->
|
||||
GetValueUnsafe();
|
||||
} else if (list_value_) {
|
||||
return static_cast<CefListValueImpl*>(list_value_.get())->GetValueUnsafe();
|
||||
}
|
||||
|
||||
return value_.get();
|
||||
}
|
||||
|
||||
|
||||
// CefBinaryValueImpl implementation.
|
||||
|
||||
@@ -441,6 +490,13 @@ bool CefBinaryValueImpl::IsEqualValue(const base::BinaryValue* that) {
|
||||
return const_value().Equals(that);
|
||||
}
|
||||
|
||||
base::BinaryValue* CefBinaryValueImpl::GetValueUnsafe() {
|
||||
if (!VerifyAttached())
|
||||
return NULL;
|
||||
controller()->AssertLockAcquired();
|
||||
return const_cast<base::BinaryValue*>(&const_value());
|
||||
}
|
||||
|
||||
bool CefBinaryValueImpl::IsValid() {
|
||||
return !detached();
|
||||
}
|
||||
@@ -572,6 +628,13 @@ bool CefDictionaryValueImpl::IsEqualValue(const base::DictionaryValue* that) {
|
||||
return const_value().Equals(that);
|
||||
}
|
||||
|
||||
base::DictionaryValue* CefDictionaryValueImpl::GetValueUnsafe() {
|
||||
if (!VerifyAttached())
|
||||
return NULL;
|
||||
controller()->AssertLockAcquired();
|
||||
return const_cast<base::DictionaryValue*>(&const_value());
|
||||
}
|
||||
|
||||
bool CefDictionaryValueImpl::IsValid() {
|
||||
return !detached();
|
||||
}
|
||||
@@ -979,6 +1042,13 @@ bool CefListValueImpl::IsEqualValue(const base::ListValue* that) {
|
||||
return const_value().Equals(that);
|
||||
}
|
||||
|
||||
base::ListValue* CefListValueImpl::GetValueUnsafe() {
|
||||
if (!VerifyAttached())
|
||||
return NULL;
|
||||
controller()->AssertLockAcquired();
|
||||
return const_cast<base::ListValue*>(&const_value());
|
||||
}
|
||||
|
||||
bool CefListValueImpl::IsValid() {
|
||||
return !detached();
|
||||
}
|
||||
|
@@ -73,9 +73,41 @@ class CefValueImpl : public CefValue {
|
||||
bool SetDictionary(CefRefPtr<CefDictionaryValue> value) override;
|
||||
bool SetList(CefRefPtr<CefListValue> value) override;
|
||||
|
||||
// Ensures exclusive access to the underlying data for the life of this scoped
|
||||
// object.
|
||||
class ScopedLockedValue {
|
||||
public:
|
||||
explicit ScopedLockedValue(CefRefPtr<CefValueImpl> impl)
|
||||
: impl_(impl) {
|
||||
impl_->AcquireLock();
|
||||
}
|
||||
~ScopedLockedValue() {
|
||||
impl_->ReleaseLock();
|
||||
}
|
||||
|
||||
base::Value* value() const {
|
||||
return impl_->GetValueUnsafe();
|
||||
}
|
||||
|
||||
private:
|
||||
CefRefPtr<CefValueImpl> impl_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedLockedValue);
|
||||
};
|
||||
|
||||
private:
|
||||
void SetValueInternal(base::Value* value);
|
||||
|
||||
// Returns the controller for the current value, if any.
|
||||
CefValueController* GetValueController() const;
|
||||
|
||||
// Explicitly lock/unlock this object and the underlying data.
|
||||
void AcquireLock();
|
||||
void ReleaseLock();
|
||||
|
||||
// Returns a reference to the underlying data. Access must be protected by
|
||||
// calling AcquireLock/ReleaseLock.
|
||||
base::Value* GetValueUnsafe() const;
|
||||
|
||||
// Access to all members must be protected by |lock_|.
|
||||
base::Lock lock_;
|
||||
|
||||
@@ -127,6 +159,10 @@ class CefBinaryValueImpl
|
||||
bool IsSameValue(const base::BinaryValue* that);
|
||||
bool IsEqualValue(const base::BinaryValue* that);
|
||||
|
||||
// Returns the underlying value. Access must be protected by calling
|
||||
// lock/unlock on the controller.
|
||||
base::BinaryValue* GetValueUnsafe();
|
||||
|
||||
// CefBinaryValue methods.
|
||||
bool IsValid() override;
|
||||
bool IsOwned() override;
|
||||
@@ -181,6 +217,10 @@ class CefDictionaryValueImpl
|
||||
bool IsSameValue(const base::DictionaryValue* that);
|
||||
bool IsEqualValue(const base::DictionaryValue* that);
|
||||
|
||||
// Returns the underlying value. Access must be protected by calling
|
||||
// lock/unlock on the controller.
|
||||
base::DictionaryValue* GetValueUnsafe();
|
||||
|
||||
// CefDictionaryValue methods.
|
||||
bool IsValid() override;
|
||||
bool IsOwned() override;
|
||||
@@ -264,7 +304,11 @@ class CefListValueImpl
|
||||
bool IsSameValue(const base::ListValue* that);
|
||||
bool IsEqualValue(const base::ListValue* that);
|
||||
|
||||
/// CefListValue methods.
|
||||
// Returns the underlying value. Access must be protected by calling
|
||||
// lock/unlock on the controller.
|
||||
base::ListValue* GetValueUnsafe();
|
||||
|
||||
// CefListValue methods.
|
||||
bool IsValid() override;
|
||||
bool IsOwned() override;
|
||||
bool IsReadOnly() override;
|
||||
|
@@ -571,6 +571,19 @@ void CefBrowserImpl::FocusedNodeChanged(const blink::WebNode& node) {
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserImpl::DraggableRegionsChanged(blink::WebFrame* frame) {
|
||||
blink::WebVector<blink::WebDraggableRegion> webregions =
|
||||
frame->document().draggableRegions();
|
||||
std::vector<Cef_DraggableRegion_Params> regions;
|
||||
for (size_t i = 0; i < webregions.size(); ++i) {
|
||||
Cef_DraggableRegion_Params region;
|
||||
region.bounds = webregions[i].bounds;
|
||||
region.draggable = webregions[i].draggable;
|
||||
regions.push_back(region);
|
||||
}
|
||||
Send(new CefHostMsg_UpdateDraggableRegions(routing_id(), regions));
|
||||
}
|
||||
|
||||
bool CefBrowserImpl::OnMessageReceived(const IPC::Message& message) {
|
||||
bool handled = true;
|
||||
IPC_BEGIN_MESSAGE_MAP(CefBrowserImpl, message)
|
||||
|
@@ -119,6 +119,7 @@ class CefBrowserImpl : public CefBrowser,
|
||||
bool is_new_navigation) override;
|
||||
void FrameDetached(blink::WebFrame* frame) override;
|
||||
void FocusedNodeChanged(const blink::WebNode& node) override;
|
||||
void DraggableRegionsChanged(blink::WebFrame* frame) override;
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
|
||||
// RenderViewObserver::OnMessageReceived message handlers.
|
||||
|
@@ -44,12 +44,45 @@ int CEF_CALLBACK drag_handler_on_drag_enter(struct _cef_drag_handler_t* self,
|
||||
return _retval;
|
||||
}
|
||||
|
||||
void CEF_CALLBACK drag_handler_on_draggable_regions_changed(
|
||||
struct _cef_drag_handler_t* self, cef_browser_t* browser,
|
||||
size_t regionsCount, cef_draggable_region_t const* regions) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return;
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser);
|
||||
if (!browser)
|
||||
return;
|
||||
// Verify param: regions; type: simple_vec_byref_const
|
||||
DCHECK(regionsCount == 0 || regions);
|
||||
if (regionsCount > 0 && !regions)
|
||||
return;
|
||||
|
||||
// Translate param: regions; type: simple_vec_byref_const
|
||||
std::vector<CefDraggableRegion > regionsList;
|
||||
if (regionsCount > 0) {
|
||||
for (size_t i = 0; i < regionsCount; ++i) {
|
||||
regionsList.push_back(regions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
CefDragHandlerCppToC::Get(self)->OnDraggableRegionsChanged(
|
||||
CefBrowserCToCpp::Wrap(browser),
|
||||
regionsList);
|
||||
}
|
||||
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefDragHandlerCppToC::CefDragHandlerCppToC(CefDragHandler* cls)
|
||||
: CefCppToC<CefDragHandlerCppToC, CefDragHandler, cef_drag_handler_t>(cls) {
|
||||
struct_.struct_.on_drag_enter = drag_handler_on_drag_enter;
|
||||
struct_.struct_.on_draggable_regions_changed =
|
||||
drag_handler_on_draggable_regions_changed;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@@ -43,6 +43,43 @@ bool CefDragHandlerCToCpp::OnDragEnter(CefRefPtr<CefBrowser> browser,
|
||||
return _retval?true:false;
|
||||
}
|
||||
|
||||
void CefDragHandlerCToCpp::OnDraggableRegionsChanged(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
const std::vector<CefDraggableRegion>& regions) {
|
||||
if (CEF_MEMBER_MISSING(struct_, on_draggable_regions_changed))
|
||||
return;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: browser; type: refptr_diff
|
||||
DCHECK(browser.get());
|
||||
if (!browser.get())
|
||||
return;
|
||||
|
||||
// Translate param: regions; type: simple_vec_byref_const
|
||||
const size_t regionsCount = regions.size();
|
||||
cef_draggable_region_t* regionsList = NULL;
|
||||
if (regionsCount > 0) {
|
||||
regionsList = new cef_draggable_region_t[regionsCount];
|
||||
DCHECK(regionsList);
|
||||
if (regionsList) {
|
||||
for (size_t i = 0; i < regionsCount; ++i) {
|
||||
regionsList[i] = regions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Execute
|
||||
struct_->on_draggable_regions_changed(struct_,
|
||||
CefBrowserCppToC::Wrap(browser),
|
||||
regionsCount,
|
||||
regionsList);
|
||||
|
||||
// Restore param:regions; type: simple_vec_byref_const
|
||||
if (regionsList)
|
||||
delete [] regionsList;
|
||||
}
|
||||
|
||||
|
||||
#ifndef NDEBUG
|
||||
template<> base::AtomicRefCount CefCToCpp<CefDragHandlerCToCpp, CefDragHandler,
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#pragma message("Warning: "__FILE__" may be accessed DLL-side only")
|
||||
#else // BUILDING_CEF_SHARED
|
||||
|
||||
#include <vector>
|
||||
#include "include/cef_drag_handler.h"
|
||||
#include "include/capi/cef_drag_handler_capi.h"
|
||||
#include "libcef_dll/ctocpp/ctocpp.h"
|
||||
@@ -35,6 +36,8 @@ class CefDragHandlerCToCpp
|
||||
// CefDragHandler methods
|
||||
bool OnDragEnter(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> dragData, DragOperationsMask mask) override;
|
||||
void OnDraggableRegionsChanged(CefRefPtr<CefBrowser> browser,
|
||||
const std::vector<CefDraggableRegion>& regions) override;
|
||||
};
|
||||
|
||||
#endif // BUILDING_CEF_SHARED
|
||||
|
@@ -309,6 +309,13 @@ CEF_EXPORT void cef_set_osmodal_loop(int osModalLoop) {
|
||||
osModalLoop?true:false);
|
||||
}
|
||||
|
||||
CEF_EXPORT void cef_enable_highdpi_support() {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
CefEnableHighDPISupport();
|
||||
}
|
||||
|
||||
CEF_EXPORT int cef_get_geolocation(
|
||||
struct _cef_get_geolocation_callback_t* callback) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
@@ -594,6 +601,81 @@ CEF_EXPORT int cef_parse_csscolor(const cef_string_t* string, int strict,
|
||||
return _retval;
|
||||
}
|
||||
|
||||
CEF_EXPORT struct _cef_value_t* cef_parse_json(const cef_string_t* json_string,
|
||||
cef_json_parser_options_t options) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: json_string; type: string_byref_const
|
||||
DCHECK(json_string);
|
||||
if (!json_string)
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
CefRefPtr<CefValue> _retval = CefParseJSON(
|
||||
CefString(json_string),
|
||||
options);
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefValueCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
CEF_EXPORT struct _cef_value_t* cef_parse_jsonand_return_error(
|
||||
const cef_string_t* json_string, cef_json_parser_options_t options,
|
||||
cef_json_parser_error_t* error_code_out, cef_string_t* error_msg_out) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: json_string; type: string_byref_const
|
||||
DCHECK(json_string);
|
||||
if (!json_string)
|
||||
return NULL;
|
||||
// Verify param: error_code_out; type: simple_byref
|
||||
DCHECK(error_code_out);
|
||||
if (!error_code_out)
|
||||
return NULL;
|
||||
// Verify param: error_msg_out; type: string_byref
|
||||
DCHECK(error_msg_out);
|
||||
if (!error_msg_out)
|
||||
return NULL;
|
||||
|
||||
// Translate param: error_code_out; type: simple_byref
|
||||
cef_json_parser_error_t error_code_outVal =
|
||||
error_code_out?*error_code_out:JSON_NO_ERROR;
|
||||
// Translate param: error_msg_out; type: string_byref
|
||||
CefString error_msg_outStr(error_msg_out);
|
||||
|
||||
// Execute
|
||||
CefRefPtr<CefValue> _retval = CefParseJSONAndReturnError(
|
||||
CefString(json_string),
|
||||
options,
|
||||
error_code_outVal,
|
||||
error_msg_outStr);
|
||||
|
||||
// Restore param: error_code_out; type: simple_byref
|
||||
if (error_code_out)
|
||||
*error_code_out = error_code_outVal;
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefValueCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
CEF_EXPORT cef_string_userfree_t cef_write_json(struct _cef_value_t* node,
|
||||
cef_json_writer_options_t options) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: node; type: refptr_same
|
||||
DCHECK(node);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
CefString _retval = CefWriteJSON(
|
||||
CefValueCppToC::Unwrap(node),
|
||||
options);
|
||||
|
||||
// Return type: string
|
||||
return _retval.DetachToUserFree();
|
||||
}
|
||||
|
||||
CEF_EXPORT int cef_get_path(cef_path_key_t key, cef_string_t* path) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
|
767
libcef_dll/wrapper/cef_resource_manager.cc
Normal file
767
libcef_dll/wrapper/cef_resource_manager.cc
Normal file
@@ -0,0 +1,767 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "include/wrapper/cef_resource_manager.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "include/base/cef_weak_ptr.h"
|
||||
#include "include/cef_parser.h"
|
||||
#include "include/wrapper/cef_stream_resource_handler.h"
|
||||
#include "include/wrapper/cef_zip_archive.h"
|
||||
|
||||
namespace {
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#define PATH_SEP '\\'
|
||||
#else
|
||||
#define PATH_SEP '/'
|
||||
#endif
|
||||
|
||||
// Returns |url| without the query or fragment components, if any.
|
||||
std::string GetUrlWithoutQueryOrFragment(const std::string& url) {
|
||||
size_t query_pos = url.find('?');
|
||||
if (query_pos != std::string::npos)
|
||||
return url.substr(0, query_pos);
|
||||
|
||||
size_t fragment_pos = url.find('#');
|
||||
if (fragment_pos != std::string::npos)
|
||||
return url.substr(0, fragment_pos);
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
// Determine the mime type based on the |url| file extension.
|
||||
std::string GetMimeType(const std::string& url) {
|
||||
std::string mime_type;
|
||||
const std::string& url_without_query = GetUrlWithoutQueryOrFragment(url);
|
||||
size_t sep = url_without_query.find_last_of(".");
|
||||
if (sep != std::string::npos) {
|
||||
mime_type = CefGetMimeType(url_without_query.substr(sep + 1));
|
||||
if (!mime_type.empty())
|
||||
return mime_type;
|
||||
}
|
||||
return "text/html";
|
||||
}
|
||||
|
||||
// Default no-op filter.
|
||||
std::string GetFilteredUrl(const std::string& url) {
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
// Provider of fixed contents.
|
||||
class ContentProvider : public CefResourceManager::Provider {
|
||||
public:
|
||||
ContentProvider(const std::string& url,
|
||||
const std::string& content,
|
||||
const std::string& mime_type)
|
||||
: url_(url),
|
||||
content_(content),
|
||||
mime_type_(mime_type) {
|
||||
DCHECK(!url.empty());
|
||||
DCHECK(!content.empty());
|
||||
}
|
||||
|
||||
bool OnRequest(scoped_refptr<CefResourceManager::Request> request) OVERRIDE {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
const std::string& url = request->url();
|
||||
if (url != url_) {
|
||||
// Not handled by this provider.
|
||||
return false;
|
||||
}
|
||||
|
||||
CefRefPtr<CefStreamReader> stream =
|
||||
CefStreamReader::CreateForData(
|
||||
static_cast<void*>(const_cast<char*>(content_.data())),
|
||||
content_.length());
|
||||
|
||||
// Determine the mime type a single time if it isn't already set.
|
||||
if (mime_type_.empty())
|
||||
mime_type_ = request->mime_type_resolver().Run(url);
|
||||
|
||||
request->Continue(new CefStreamResourceHandler(mime_type_, stream));
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string url_;
|
||||
std::string content_;
|
||||
std::string mime_type_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ContentProvider);
|
||||
};
|
||||
|
||||
|
||||
// Provider of contents loaded from a directory on the file system.
|
||||
class DirectoryProvider : public CefResourceManager::Provider {
|
||||
public:
|
||||
DirectoryProvider(const std::string& url_path,
|
||||
const std::string& directory_path)
|
||||
: url_path_(url_path),
|
||||
directory_path_(directory_path) {
|
||||
DCHECK(!url_path_.empty());
|
||||
DCHECK(!directory_path_.empty());
|
||||
|
||||
// Normalize the path values.
|
||||
if (url_path_[url_path_.size() - 1] != '/')
|
||||
url_path_ += '/';
|
||||
if (directory_path_[directory_path_.size() - 1] != PATH_SEP)
|
||||
directory_path_ += PATH_SEP;
|
||||
}
|
||||
|
||||
bool OnRequest(scoped_refptr<CefResourceManager::Request> request) OVERRIDE {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
const std::string& url = request->url();
|
||||
if (url.find(url_path_) != 0U) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& file_path = GetFilePath(url);
|
||||
|
||||
// Open |file_path| on the FILE thread.
|
||||
CefPostTask(TID_FILE,
|
||||
base::Bind(&DirectoryProvider::OpenOnFileThread, file_path, request));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string GetFilePath(const std::string& url) {
|
||||
std::string path_part = url.substr(url_path_.length());
|
||||
#if defined(OS_WIN)
|
||||
std::replace(path_part.begin(), path_part.end(), '/', '\\');
|
||||
#endif
|
||||
return directory_path_ + path_part;
|
||||
}
|
||||
|
||||
static void OpenOnFileThread(
|
||||
const std::string& file_path,
|
||||
scoped_refptr<CefResourceManager::Request> request) {
|
||||
CEF_REQUIRE_FILE_THREAD();
|
||||
|
||||
CefRefPtr<CefStreamReader> stream =
|
||||
CefStreamReader::CreateForFile(file_path);
|
||||
|
||||
// Continue loading on the IO thread.
|
||||
CefPostTask(TID_IO,
|
||||
base::Bind(&DirectoryProvider::ContinueOpenOnIOThread, request,
|
||||
stream));
|
||||
}
|
||||
|
||||
static void ContinueOpenOnIOThread(
|
||||
scoped_refptr<CefResourceManager::Request> request,
|
||||
CefRefPtr<CefStreamReader> stream) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
CefRefPtr<CefStreamResourceHandler> handler;
|
||||
if (stream.get()) {
|
||||
handler = new CefStreamResourceHandler(
|
||||
request->mime_type_resolver().Run(request->url()),
|
||||
stream);
|
||||
}
|
||||
request->Continue(handler);
|
||||
}
|
||||
|
||||
std::string url_path_;
|
||||
std::string directory_path_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DirectoryProvider);
|
||||
};
|
||||
|
||||
|
||||
// Provider of contents loaded from an archive file.
|
||||
class ArchiveProvider : public CefResourceManager::Provider {
|
||||
public:
|
||||
ArchiveProvider(const std::string& url_path,
|
||||
const std::string& archive_path,
|
||||
const std::string& password)
|
||||
: url_path_(url_path),
|
||||
archive_path_(archive_path),
|
||||
password_(password),
|
||||
archive_load_started_(false),
|
||||
archive_load_ended_(false),
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(!url_path_.empty());
|
||||
DCHECK(!archive_path_.empty());
|
||||
|
||||
// Normalize the path values.
|
||||
if (url_path_[url_path_.size() - 1] != '/')
|
||||
url_path_ += '/';
|
||||
}
|
||||
|
||||
bool OnRequest(scoped_refptr<CefResourceManager::Request> request) OVERRIDE {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
const std::string& url = request->url();
|
||||
if (url.find(url_path_) != 0U) {
|
||||
// Not handled by this provider.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!archive_load_started_) {
|
||||
// Initiate archive loading and queue the pending request.
|
||||
archive_load_started_ = true;
|
||||
pending_requests_.push_back(request);
|
||||
|
||||
// Load the archive file on the FILE thread.
|
||||
CefPostTask(TID_FILE,
|
||||
base::Bind(&ArchiveProvider::LoadOnFileThread,
|
||||
weak_ptr_factory_.GetWeakPtr(), archive_path_, password_));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (archive_load_started_ && !archive_load_ended_) {
|
||||
// The archive load has already started. Queue the pending request.
|
||||
pending_requests_.push_back(request);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Archive loading is done.
|
||||
return ContinueRequest(request);
|
||||
}
|
||||
|
||||
private:
|
||||
static void LoadOnFileThread(base::WeakPtr<ArchiveProvider> ptr,
|
||||
const std::string& archive_path,
|
||||
const std::string& password) {
|
||||
CEF_REQUIRE_FILE_THREAD();
|
||||
|
||||
CefRefPtr<CefZipArchive> archive;
|
||||
|
||||
CefRefPtr<CefStreamReader> stream =
|
||||
CefStreamReader::CreateForFile(archive_path);
|
||||
if (stream.get()) {
|
||||
archive = new CefZipArchive;
|
||||
if (archive->Load(stream, password, true) == 0) {
|
||||
DLOG(WARNING) << "Empty archive file: " << archive_path;
|
||||
archive = NULL;
|
||||
}
|
||||
} else {
|
||||
DLOG(WARNING) << "Failed to load archive file: " << archive_path;
|
||||
}
|
||||
|
||||
CefPostTask(TID_IO,
|
||||
base::Bind(&ArchiveProvider::ContinueOnIOThread, ptr, archive));
|
||||
}
|
||||
|
||||
void ContinueOnIOThread(CefRefPtr<CefZipArchive> archive) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
archive_load_ended_ = true;
|
||||
archive_ = archive;
|
||||
|
||||
if (!pending_requests_.empty()) {
|
||||
// Continue all pending requests.
|
||||
PendingRequests::const_iterator it = pending_requests_.begin();
|
||||
for (; it != pending_requests_.end(); ++it)
|
||||
ContinueRequest(*it);
|
||||
pending_requests_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool ContinueRequest(scoped_refptr<CefResourceManager::Request> request) {
|
||||
CefRefPtr<CefResourceHandler> handler;
|
||||
|
||||
// |archive_| will be NULL if the archive file failed to load or was empty.
|
||||
if (archive_.get()) {
|
||||
const std::string& url = request->url();
|
||||
const std::string& relative_path = url.substr(url_path_.length());
|
||||
CefRefPtr<CefZipArchive::File> file = archive_->GetFile(relative_path);
|
||||
if (file.get()) {
|
||||
handler = new CefStreamResourceHandler(
|
||||
request->mime_type_resolver().Run(url),
|
||||
file->GetStreamReader());
|
||||
}
|
||||
}
|
||||
|
||||
if (!handler.get())
|
||||
return false;
|
||||
|
||||
request->Continue(handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string url_path_;
|
||||
std::string archive_path_;
|
||||
std::string password_;
|
||||
|
||||
bool archive_load_started_;
|
||||
bool archive_load_ended_;
|
||||
CefRefPtr<CefZipArchive> archive_;
|
||||
|
||||
// List of requests that are pending while the archive is being loaded.
|
||||
typedef std::vector<scoped_refptr<CefResourceManager::Request> >
|
||||
PendingRequests;
|
||||
PendingRequests pending_requests_;
|
||||
|
||||
// Must be the last member.
|
||||
base::WeakPtrFactory<ArchiveProvider> weak_ptr_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ArchiveProvider);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// CefResourceManager::ProviderEntry implementation.
|
||||
|
||||
struct CefResourceManager::ProviderEntry {
|
||||
ProviderEntry(Provider* provider,
|
||||
int order,
|
||||
const std::string& identifier)
|
||||
: provider_(provider),
|
||||
order_(order),
|
||||
identifier_(identifier),
|
||||
deletion_pending_(false) {
|
||||
}
|
||||
|
||||
scoped_ptr<Provider> provider_;
|
||||
int order_;
|
||||
std::string identifier_;
|
||||
|
||||
// List of pending requests currently associated with this provider.
|
||||
RequestList pending_requests_;
|
||||
|
||||
// True if deletion of this provider is pending.
|
||||
bool deletion_pending_;
|
||||
};
|
||||
|
||||
|
||||
// CefResourceManager::RequestState implementation.
|
||||
|
||||
CefResourceManager::RequestState::~RequestState() {
|
||||
// Always execute the callback.
|
||||
if (callback_.get())
|
||||
callback_->Continue(true);
|
||||
}
|
||||
|
||||
|
||||
// CefResourceManager::Request implementation.
|
||||
|
||||
void CefResourceManager::Request::Continue(
|
||||
CefRefPtr<CefResourceHandler> handler) {
|
||||
if (!CefCurrentlyOn(TID_IO)) {
|
||||
CefPostTask(TID_IO,
|
||||
base::Bind(&CefResourceManager::Request::Continue, this, handler));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state_.get())
|
||||
return;
|
||||
|
||||
// Disassociate |state_| immediately so that Provider::OnRequestCanceled is
|
||||
// not called unexpectedly if Provider::OnRequest calls this method and then
|
||||
// calls CefResourceManager::Remove*.
|
||||
CefPostTask(TID_IO,
|
||||
base::Bind(&CefResourceManager::Request::ContinueOnIOThread,
|
||||
base::Passed(&state_), handler));
|
||||
}
|
||||
|
||||
void CefResourceManager::Request::Stop() {
|
||||
if (!CefCurrentlyOn(TID_IO)) {
|
||||
CefPostTask(TID_IO,
|
||||
base::Bind(&CefResourceManager::Request::Stop, this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state_.get())
|
||||
return;
|
||||
|
||||
// Disassociate |state_| immediately so that Provider::OnRequestCanceled is
|
||||
// not called unexpectedly if Provider::OnRequest calls this method and then
|
||||
// calls CefResourceManager::Remove*.
|
||||
CefPostTask(TID_IO,
|
||||
base::Bind(&CefResourceManager::Request::StopOnIOThread,
|
||||
base::Passed(&state_)));
|
||||
}
|
||||
|
||||
CefResourceManager::Request::Request(scoped_ptr<RequestState> state)
|
||||
: state_(state.Pass()),
|
||||
params_(state_->params_) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
ProviderEntry* entry = *(state_->current_entry_pos_);
|
||||
// Should not be on a deleted entry.
|
||||
DCHECK(!entry->deletion_pending_);
|
||||
|
||||
// Add this request to the entry's pending request list.
|
||||
entry->pending_requests_.push_back(this);
|
||||
state_->current_request_pos_ = --entry->pending_requests_.end();
|
||||
}
|
||||
|
||||
// Detaches and returns |state_| if the provider indicates that it will not
|
||||
// handle the request. Note that |state_| may already be NULL if OnRequest
|
||||
// executes a callback before returning, in which case execution will continue
|
||||
// asynchronously in any case.
|
||||
scoped_ptr<CefResourceManager::RequestState>
|
||||
CefResourceManager::Request::SendRequest() {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
Provider* provider = (*state_->current_entry_pos_)->provider_.get();
|
||||
if (!provider->OnRequest(this))
|
||||
return state_.Pass();
|
||||
return scoped_ptr<RequestState>();
|
||||
}
|
||||
|
||||
bool CefResourceManager::Request::HasState() {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
return (state_.get() != NULL);
|
||||
}
|
||||
|
||||
// static
|
||||
void CefResourceManager::Request::ContinueOnIOThread(
|
||||
scoped_ptr<RequestState> state,
|
||||
CefRefPtr<CefResourceHandler> handler) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
// The manager may already have been deleted.
|
||||
base::WeakPtr<CefResourceManager> manager = state->manager_;
|
||||
if (manager)
|
||||
manager->ContinueRequest(state.Pass(), handler);
|
||||
}
|
||||
|
||||
// static
|
||||
void CefResourceManager::Request::StopOnIOThread(
|
||||
scoped_ptr<RequestState> state) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
// The manager may already have been deleted.
|
||||
base::WeakPtr<CefResourceManager> manager = state->manager_;
|
||||
if (manager)
|
||||
manager->StopRequest(state.Pass());
|
||||
}
|
||||
|
||||
|
||||
// CefResourceManager implementation.
|
||||
|
||||
CefResourceManager::CefResourceManager()
|
||||
: url_filter_(base::Bind(GetFilteredUrl)),
|
||||
mime_type_resolver_(base::Bind(GetMimeType)),
|
||||
weak_ptr_factory_(this) {
|
||||
}
|
||||
|
||||
CefResourceManager::~CefResourceManager() {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
RemoveAllProviders();
|
||||
|
||||
// Delete all entryies now. Requests may still be pending but they will not
|
||||
// call back into this manager due to the use of WeakPtr.
|
||||
if (!providers_.empty()) {
|
||||
ProviderEntryList::iterator it = providers_.begin();
|
||||
for (; it != providers_.end(); ++it)
|
||||
delete *it;
|
||||
providers_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void CefResourceManager::AddContentProvider(const std::string& url,
|
||||
const std::string& content,
|
||||
const std::string& mime_type,
|
||||
int order,
|
||||
const std::string& identifier) {
|
||||
AddProvider(new ContentProvider(url, content, mime_type), order, identifier);
|
||||
}
|
||||
|
||||
void CefResourceManager::AddDirectoryProvider(
|
||||
const std::string& url_path,
|
||||
const std::string& directory_path,
|
||||
int order,
|
||||
const std::string& identifier) {
|
||||
AddProvider(new DirectoryProvider(url_path, directory_path),
|
||||
order, identifier);
|
||||
}
|
||||
|
||||
void CefResourceManager::AddArchiveProvider(const std::string& url_path,
|
||||
const std::string& archive_path,
|
||||
const std::string& password,
|
||||
int order,
|
||||
const std::string& identifier) {
|
||||
AddProvider(new ArchiveProvider(url_path, archive_path, password),
|
||||
order, identifier);
|
||||
}
|
||||
|
||||
void CefResourceManager::AddProvider(Provider* provider,
|
||||
int order,
|
||||
const std::string& identifier) {
|
||||
DCHECK(provider);
|
||||
if (!provider)
|
||||
return;
|
||||
|
||||
if (!CefCurrentlyOn(TID_IO)) {
|
||||
CefPostTask(TID_IO,
|
||||
base::Bind(&CefResourceManager::AddProvider, this, provider, order,
|
||||
identifier));
|
||||
return;
|
||||
}
|
||||
|
||||
scoped_ptr<ProviderEntry> new_entry(
|
||||
new ProviderEntry(provider, order, identifier));
|
||||
|
||||
if (providers_.empty()) {
|
||||
providers_.push_back(new_entry.release());
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert before the first entry with a higher |order| value.
|
||||
ProviderEntryList::iterator it = providers_.begin();
|
||||
for (; it != providers_.end(); ++it) {
|
||||
if ((*it)->order_ > order)
|
||||
break;
|
||||
}
|
||||
|
||||
providers_.insert(it, new_entry.release());
|
||||
}
|
||||
|
||||
void CefResourceManager::RemoveProviders(const std::string& identifier) {
|
||||
if (!CefCurrentlyOn(TID_IO)) {
|
||||
CefPostTask(TID_IO,
|
||||
base::Bind(&CefResourceManager::RemoveProviders, this, identifier));
|
||||
return;
|
||||
}
|
||||
|
||||
if (providers_.empty())
|
||||
return;
|
||||
|
||||
ProviderEntryList::iterator it = providers_.begin();
|
||||
while (it != providers_.end()) {
|
||||
if ((*it)->identifier_ == identifier)
|
||||
DeleteProvider(it, false);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void CefResourceManager::RemoveAllProviders() {
|
||||
if (!CefCurrentlyOn(TID_IO)) {
|
||||
CefPostTask(TID_IO,
|
||||
base::Bind(&CefResourceManager::RemoveAllProviders, this));
|
||||
return;
|
||||
}
|
||||
|
||||
if (providers_.empty())
|
||||
return;
|
||||
|
||||
ProviderEntryList::iterator it = providers_.begin();
|
||||
while (it != providers_.end())
|
||||
DeleteProvider(it, true);
|
||||
}
|
||||
|
||||
void CefResourceManager::SetMimeTypeResolver(const MimeTypeResolver& resolver) {
|
||||
if (!CefCurrentlyOn(TID_IO)) {
|
||||
CefPostTask(TID_IO,
|
||||
base::Bind(&CefResourceManager::SetMimeTypeResolver, this, resolver));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!resolver.is_null())
|
||||
mime_type_resolver_ = resolver;
|
||||
else
|
||||
mime_type_resolver_ = base::Bind(GetMimeType);
|
||||
}
|
||||
|
||||
void CefResourceManager::SetUrlFilter(const UrlFilter& filter) {
|
||||
if (!CefCurrentlyOn(TID_IO)) {
|
||||
CefPostTask(TID_IO,
|
||||
base::Bind(&CefResourceManager::SetUrlFilter, this, filter));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!filter.is_null())
|
||||
url_filter_ = filter;
|
||||
else
|
||||
url_filter_ = base::Bind(GetFilteredUrl);
|
||||
}
|
||||
|
||||
cef_return_value_t CefResourceManager::OnBeforeResourceLoad(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefRequestCallback> callback) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
// Find the first provider that is not pending deletion.
|
||||
ProviderEntryList::iterator current_entry_pos = providers_.begin();
|
||||
GetNextValidProvider(current_entry_pos);
|
||||
|
||||
if (current_entry_pos == providers_.end()) {
|
||||
// No providers so continue the request immediately.
|
||||
return RV_CONTINUE;
|
||||
}
|
||||
|
||||
scoped_ptr<RequestState> state(new RequestState);
|
||||
|
||||
state->manager_ = weak_ptr_factory_.GetWeakPtr();
|
||||
state->callback_ = callback;
|
||||
|
||||
state->params_.url_ =
|
||||
GetUrlWithoutQueryOrFragment(url_filter_.Run(request->GetURL()));
|
||||
state->params_.browser_ = browser;
|
||||
state->params_.frame_ = frame;
|
||||
state->params_.request_ = request;
|
||||
state->params_.url_filter_ = url_filter_;
|
||||
state->params_.mime_type_resolver_ = mime_type_resolver_;
|
||||
|
||||
state->current_entry_pos_ = current_entry_pos;
|
||||
|
||||
// If the request is potentially handled we need to continue asynchronously.
|
||||
return SendRequest(state.Pass()) ? RV_CONTINUE_ASYNC : RV_CONTINUE;
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> CefResourceManager::GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
if (pending_handlers_.empty())
|
||||
return NULL;
|
||||
|
||||
CefRefPtr<CefResourceHandler> handler;
|
||||
|
||||
PendingHandlersMap::iterator it =
|
||||
pending_handlers_.find(request->GetIdentifier());
|
||||
if (it != pending_handlers_.end()) {
|
||||
handler = it->second;
|
||||
pending_handlers_.erase(it);
|
||||
}
|
||||
|
||||
return handler;
|
||||
}
|
||||
|
||||
// Send the request to providers in order until one potentially handles it or we
|
||||
// run out of providers. Returns true if the request is potentially handled.
|
||||
bool CefResourceManager::SendRequest(scoped_ptr<RequestState> state) {
|
||||
bool potentially_handled = false;
|
||||
|
||||
do {
|
||||
// Should not be on the last provider entry.
|
||||
DCHECK(state->current_entry_pos_ != providers_.end());
|
||||
scoped_refptr<Request> request = new Request(state.Pass());
|
||||
|
||||
// Give the provider an opportunity to handle the request.
|
||||
state = request->SendRequest();
|
||||
if (state.get()) {
|
||||
// The provider will not handle the request. Move to the next provider if
|
||||
// any.
|
||||
if (!IncrementProvider(state.get()))
|
||||
StopRequest(state.Pass());
|
||||
} else {
|
||||
potentially_handled = true;
|
||||
}
|
||||
} while (state.get());
|
||||
|
||||
return potentially_handled;
|
||||
}
|
||||
|
||||
void CefResourceManager::ContinueRequest(
|
||||
scoped_ptr<RequestState> state,
|
||||
CefRefPtr<CefResourceHandler> handler) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
if (handler.get()) {
|
||||
// The request has been handled. Associate the request ID with the handler.
|
||||
pending_handlers_.insert(
|
||||
std::make_pair(state->params_.request_->GetIdentifier(), handler));
|
||||
StopRequest(state.Pass());
|
||||
} else {
|
||||
// Move to the next provider if any.
|
||||
if (IncrementProvider(state.get()))
|
||||
SendRequest(state.Pass());
|
||||
else
|
||||
StopRequest(state.Pass());
|
||||
}
|
||||
}
|
||||
|
||||
void CefResourceManager::StopRequest(scoped_ptr<RequestState> state) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
// Detach from the current provider.
|
||||
DetachRequestFromProvider(state.get());
|
||||
|
||||
// Delete the state object and execute the callback.
|
||||
state.reset();
|
||||
}
|
||||
|
||||
// Move state to the next provider if any and return true if there are more
|
||||
// providers.
|
||||
bool CefResourceManager::IncrementProvider(RequestState* state) {
|
||||
// Identify the next provider.
|
||||
ProviderEntryList::iterator next_entry_pos = state->current_entry_pos_;
|
||||
GetNextValidProvider(++next_entry_pos);
|
||||
|
||||
// Detach from the current provider.
|
||||
DetachRequestFromProvider(state);
|
||||
|
||||
if (next_entry_pos != providers_.end()) {
|
||||
// Update the state to reference the new provider entry.
|
||||
state->current_entry_pos_ = next_entry_pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// The new provider, if any, should be determined before calling this method.
|
||||
void CefResourceManager::DetachRequestFromProvider(RequestState* state) {
|
||||
if (state->current_entry_pos_ != providers_.end()) {
|
||||
// Remove the association from the current provider entry.
|
||||
ProviderEntryList::iterator current_entry_pos =
|
||||
state->current_entry_pos_;
|
||||
ProviderEntry* current_entry = *(current_entry_pos);
|
||||
current_entry->pending_requests_.erase(state->current_request_pos_);
|
||||
|
||||
if (current_entry->deletion_pending_ &&
|
||||
current_entry->pending_requests_.empty()) {
|
||||
// Delete the current provider entry now.
|
||||
providers_.erase(current_entry_pos);
|
||||
delete current_entry;
|
||||
}
|
||||
|
||||
// Set to the end for error checking purposes.
|
||||
state->current_entry_pos_ = providers_.end();
|
||||
}
|
||||
}
|
||||
|
||||
// Move to the next provider that is not pending deletion.
|
||||
void CefResourceManager::GetNextValidProvider(
|
||||
ProviderEntryList::iterator& iterator) {
|
||||
while (iterator != providers_.end() && (*iterator)->deletion_pending_) {
|
||||
++iterator;
|
||||
}
|
||||
}
|
||||
|
||||
void CefResourceManager::DeleteProvider(ProviderEntryList::iterator& iterator,
|
||||
bool stop) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
ProviderEntry* current_entry = *(iterator);
|
||||
|
||||
if (current_entry->deletion_pending_)
|
||||
return;
|
||||
|
||||
if (!current_entry->pending_requests_.empty()) {
|
||||
// Don't delete the provider entry until all pending requests have cleared.
|
||||
current_entry->deletion_pending_ = true;
|
||||
|
||||
// Continue pending requests immediately.
|
||||
RequestList::iterator it = current_entry->pending_requests_.begin();
|
||||
for (; it != current_entry->pending_requests_.end(); ++it) {
|
||||
const scoped_refptr<Request>& request = *it;
|
||||
if (request->HasState()) {
|
||||
if (stop)
|
||||
request->Stop();
|
||||
else
|
||||
request->Continue(NULL);
|
||||
current_entry->provider_->OnRequestCanceled(request);
|
||||
}
|
||||
}
|
||||
|
||||
++iterator;
|
||||
} else {
|
||||
// Delete the provider entry now.
|
||||
iterator = providers_.erase(iterator);
|
||||
delete current_entry;
|
||||
}
|
||||
}
|
@@ -301,6 +301,13 @@ CEF_GLOBAL void CefSetOSModalLoop(bool osModalLoop) {
|
||||
osModalLoop);
|
||||
}
|
||||
|
||||
CEF_GLOBAL void CefEnableHighDPISupport() {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
cef_enable_highdpi_support();
|
||||
}
|
||||
|
||||
CEF_GLOBAL bool CefGetGeolocation(
|
||||
CefRefPtr<CefGetGeolocationCallback> callback) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
@@ -549,6 +556,65 @@ CEF_GLOBAL bool CefParseCSSColor(const CefString& string, bool strict,
|
||||
return _retval?true:false;
|
||||
}
|
||||
|
||||
CEF_GLOBAL CefRefPtr<CefValue> CefParseJSON(const CefString& json_string,
|
||||
cef_json_parser_options_t options) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: json_string; type: string_byref_const
|
||||
DCHECK(!json_string.empty());
|
||||
if (json_string.empty())
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
cef_value_t* _retval = cef_parse_json(
|
||||
json_string.GetStruct(),
|
||||
options);
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefValueCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
CEF_GLOBAL CefRefPtr<CefValue> CefParseJSONAndReturnError(
|
||||
const CefString& json_string, cef_json_parser_options_t options,
|
||||
cef_json_parser_error_t& error_code_out, CefString& error_msg_out) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: json_string; type: string_byref_const
|
||||
DCHECK(!json_string.empty());
|
||||
if (json_string.empty())
|
||||
return NULL;
|
||||
|
||||
// Execute
|
||||
cef_value_t* _retval = cef_parse_jsonand_return_error(
|
||||
json_string.GetStruct(),
|
||||
options,
|
||||
&error_code_out,
|
||||
error_msg_out.GetWritableStruct());
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefValueCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
CEF_GLOBAL CefString CefWriteJSON(CefRefPtr<CefValue> node,
|
||||
cef_json_writer_options_t options) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: node; type: refptr_same
|
||||
DCHECK(node.get());
|
||||
if (!node.get())
|
||||
return CefString();
|
||||
|
||||
// Execute
|
||||
cef_string_userfree_t _retval = cef_write_json(
|
||||
CefValueCToCpp::Unwrap(node),
|
||||
options);
|
||||
|
||||
// Return type: string
|
||||
CefString _retvalStr;
|
||||
_retvalStr.AttachToUserFree(_retval);
|
||||
return _retvalStr;
|
||||
}
|
||||
|
||||
CEF_GLOBAL bool CefGetPath(PathKey key, CefString& path) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
|
@@ -149,4 +149,29 @@ patches = [
|
||||
'name': 'chrome_pepper_flash_1586',
|
||||
'path': '../chrome/common/',
|
||||
},
|
||||
{
|
||||
# Fix placement of IME window on Windows.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issue/1610
|
||||
'name': 'ime_1610',
|
||||
'path': '../ui/base/ime/',
|
||||
},
|
||||
{
|
||||
# Remove DCHECK on Linux when initialized CEF from a non-main thread.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issue/1639
|
||||
'name': 'process_title_1639',
|
||||
'path': '../content/common/',
|
||||
},
|
||||
{
|
||||
# Fix ScriptForbiddenScope assertion.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issue/1643
|
||||
# https://codereview.chromium.org/1096553003
|
||||
'name': 'webkit_parser_scriptforbidden_1643',
|
||||
'path': '../third_party/WebKit/Source/',
|
||||
},
|
||||
{
|
||||
# Fix multiple handling of WM_MOUSEWHEEL messages on Windows.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/1481
|
||||
'name': 'hwnd_message_handler_1481',
|
||||
'path': '../ui/views/win/',
|
||||
},
|
||||
]
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git web_contents_impl.cc web_contents_impl.cc
|
||||
index 24122cd..52cd0c6 100644
|
||||
index f831fba..0d37bdf 100644
|
||||
--- web_contents_impl.cc
|
||||
+++ web_contents_impl.cc
|
||||
@@ -1205,22 +1205,29 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
diff --git common.gypi common.gypi
|
||||
index dccdfec..65b9540 100644
|
||||
index 066b0b4..96e4d6b 100644
|
||||
--- common.gypi
|
||||
+++ common.gypi
|
||||
@@ -9,6 +9,9 @@
|
||||
|
@@ -39,10 +39,10 @@ index ca4d51d..5df0485 100644
|
||||
// Returns true if we should fork a new process for the given navigation.
|
||||
// If |send_referrer| is set to false (which is the default), no referrer
|
||||
diff --git renderer/render_frame_impl.cc renderer/render_frame_impl.cc
|
||||
index 88b26d2..07ed0cb 100644
|
||||
index 586b92b..b9ffbcd 100644
|
||||
--- renderer/render_frame_impl.cc
|
||||
+++ renderer/render_frame_impl.cc
|
||||
@@ -4076,7 +4076,6 @@ void RenderFrameImpl::OnCommitNavigation(
|
||||
@@ -4153,7 +4153,6 @@ void RenderFrameImpl::OnCommitNavigation(
|
||||
WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
|
||||
RenderFrame* render_frame,
|
||||
const NavigationPolicyInfo& info) {
|
||||
@@ -50,7 +50,7 @@ index 88b26d2..07ed0cb 100644
|
||||
// The handlenavigation API is deprecated and will be removed once
|
||||
// crbug.com/325351 is resolved.
|
||||
if (info.urlRequest.url() != GURL(kSwappedOutURL) &&
|
||||
@@ -4091,7 +4090,6 @@ WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
|
||||
@@ -4168,7 +4167,6 @@ WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
|
||||
info.isRedirect)) {
|
||||
return blink::WebNavigationPolicyIgnore;
|
||||
}
|
||||
|
19
patch/patches/hwnd_message_handler_1481.patch
Normal file
19
patch/patches/hwnd_message_handler_1481.patch
Normal file
@@ -0,0 +1,19 @@
|
||||
diff --git hwnd_message_handler.cc hwnd_message_handler.cc
|
||||
index 9956006..1a926e4 100644
|
||||
--- hwnd_message_handler.cc
|
||||
+++ hwnd_message_handler.cc
|
||||
@@ -2774,8 +2774,12 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message,
|
||||
"440919 HWNDMessageHandler::HandleMouseEventInternal6"));
|
||||
|
||||
// Reroute the mouse wheel to the window under the pointer if applicable.
|
||||
- return (ui::RerouteMouseWheel(hwnd(), w_param, l_param) ||
|
||||
- delegate_->HandleMouseEvent(ui::MouseWheelEvent(msg))) ? 0 : 1;
|
||||
+ if (ui::RerouteMouseWheel(hwnd(), w_param, l_param) ||
|
||||
+ delegate_->HandleMouseEvent(ui::MouseWheelEvent(msg))) {
|
||||
+ SetMsgHandled(TRUE);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
// TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
|
15
patch/patches/ime_1610.patch
Normal file
15
patch/patches/ime_1610.patch
Normal file
@@ -0,0 +1,15 @@
|
||||
diff --git input_method_win.cc input_method_win.cc
|
||||
index 6961683..1f8c4b2 100644
|
||||
--- input_method_win.cc
|
||||
+++ input_method_win.cc
|
||||
@@ -601,7 +601,9 @@ bool InputMethodWin::IsWindowFocused(const TextInputClient* client) const {
|
||||
// receiving keyboard input as long as it is an active window. This works well
|
||||
// even when the |attached_window_handle| becomes active but has not received
|
||||
// WM_FOCUS yet.
|
||||
- return attached_window_handle && GetActiveWindow() == attached_window_handle;
|
||||
+ // With CEF |attached_window_handle| may be a child window.
|
||||
+ return attached_window_handle &&
|
||||
+ GetActiveWindow() == ::GetAncestor(attached_window_handle, GA_ROOT);
|
||||
}
|
||||
|
||||
bool InputMethodWin::DispatchFabricatedKeyEvent(const ui::KeyEvent& event) {
|
@@ -11,7 +11,7 @@ index 53f1128..46bbcf8 100644
|
||||
IPC_STRUCT_TRAITS_MEMBER(navigate_on_drag_drop)
|
||||
IPC_STRUCT_TRAITS_MEMBER(spatial_navigation_enabled)
|
||||
diff --git public/common/web_preferences.cc public/common/web_preferences.cc
|
||||
index b61e1dc..5b55207 100644
|
||||
index 039a5ff..6c2e08c 100644
|
||||
--- public/common/web_preferences.cc
|
||||
+++ public/common/web_preferences.cc
|
||||
@@ -189,6 +189,7 @@ WebPreferences::WebPreferences()
|
||||
@@ -35,7 +35,7 @@ index 8d25487..23b25ae 100644
|
||||
bool slimming_paint_enabled;
|
||||
|
||||
diff --git renderer/render_view_impl.cc renderer/render_view_impl.cc
|
||||
index c9cbd66..8124639 100644
|
||||
index 84340d4..76187de 100644
|
||||
--- renderer/render_view_impl.cc
|
||||
+++ renderer/render_view_impl.cc
|
||||
@@ -932,6 +932,8 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
|
||||
|
13
patch/patches/process_title_1639.patch
Normal file
13
patch/patches/process_title_1639.patch
Normal file
@@ -0,0 +1,13 @@
|
||||
diff --git set_process_title.cc set_process_title.cc
|
||||
index 74651ca6..439d5ea 100644
|
||||
--- set_process_title.cc
|
||||
+++ set_process_title.cc
|
||||
@@ -42,7 +42,7 @@ void SetProcessTitleFromCommandLine(const char** main_argv) {
|
||||
bool have_argv0 = false;
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
- DCHECK_EQ(base::PlatformThread::CurrentId(), getpid());
|
||||
+ //DCHECK_EQ(base::PlatformThread::CurrentId(), getpid());
|
||||
|
||||
if (main_argv)
|
||||
setproctitle_init(main_argv);
|
@@ -1,8 +1,8 @@
|
||||
diff --git render_process_host_impl.cc render_process_host_impl.cc
|
||||
index 91dd8b3..3cba806 100644
|
||||
index 8a5e6b4..1a8ca8b 100644
|
||||
--- render_process_host_impl.cc
|
||||
+++ render_process_host_impl.cc
|
||||
@@ -2089,6 +2089,8 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead,
|
||||
@@ -2090,6 +2090,8 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead,
|
||||
#endif
|
||||
RemoveUserData(kSessionStorageHolderKey);
|
||||
|
||||
@@ -11,7 +11,7 @@ index 91dd8b3..3cba806 100644
|
||||
IDMap<IPC::Listener>::iterator iter(&listeners_);
|
||||
while (!iter.IsAtEnd()) {
|
||||
iter.GetCurrentValue()->OnMessageReceived(
|
||||
@@ -2098,8 +2100,6 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead,
|
||||
@@ -2099,8 +2101,6 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead,
|
||||
iter.Advance();
|
||||
}
|
||||
|
||||
|
@@ -43,7 +43,7 @@ index b53fc7f..0b24d2a 100644
|
||||
if (input_method)
|
||||
input_method->OnBlur();
|
||||
diff --git desktop_aura/desktop_window_tree_host_x11.cc desktop_aura/desktop_window_tree_host_x11.cc
|
||||
index 1316b8b..588e591 100644
|
||||
index 01661a8..3321846 100644
|
||||
--- desktop_aura/desktop_window_tree_host_x11.cc
|
||||
+++ desktop_aura/desktop_window_tree_host_x11.cc
|
||||
@@ -153,7 +153,8 @@ DesktopWindowTreeHostX11::DesktopWindowTreeHostX11(
|
||||
@@ -75,7 +75,7 @@ index 1316b8b..588e591 100644
|
||||
return ToDIPRect(bounds_in_pixels_);
|
||||
}
|
||||
|
||||
@@ -894,6 +898,8 @@ void DesktopWindowTreeHostX11::Hide() {
|
||||
@@ -892,6 +896,8 @@ void DesktopWindowTreeHostX11::Hide() {
|
||||
}
|
||||
|
||||
gfx::Rect DesktopWindowTreeHostX11::GetBounds() const {
|
||||
@@ -84,7 +84,7 @@ index 1316b8b..588e591 100644
|
||||
return bounds_in_pixels_;
|
||||
}
|
||||
|
||||
@@ -950,6 +956,8 @@ void DesktopWindowTreeHostX11::SetBounds(
|
||||
@@ -948,6 +954,8 @@ void DesktopWindowTreeHostX11::SetBounds(
|
||||
}
|
||||
|
||||
gfx::Point DesktopWindowTreeHostX11::GetLocationOnNativeScreen() const {
|
||||
@@ -93,7 +93,7 @@ index 1316b8b..588e591 100644
|
||||
return bounds_in_pixels_.origin();
|
||||
}
|
||||
|
||||
@@ -1070,9 +1078,13 @@ void DesktopWindowTreeHostX11::InitX11Window(
|
||||
@@ -1068,9 +1076,13 @@ void DesktopWindowTreeHostX11::InitX11Window(
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ index 1316b8b..588e591 100644
|
||||
bounds_in_pixels_.y(), bounds_in_pixels_.width(),
|
||||
bounds_in_pixels_.height(),
|
||||
0, // border width
|
||||
@@ -1717,6 +1729,10 @@ uint32_t DesktopWindowTreeHostX11::DispatchEvent(
|
||||
@@ -1715,6 +1727,10 @@ uint32_t DesktopWindowTreeHostX11::DispatchEvent(
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
36
patch/patches/webkit_parser_scriptforbidden_1643.patch
Normal file
36
patch/patches/webkit_parser_scriptforbidden_1643.patch
Normal file
@@ -0,0 +1,36 @@
|
||||
diff --git core/html/parser/HTMLConstructionSite.cpp core/html/parser/HTMLConstructionSite.cpp
|
||||
index 679749a..487323d 100644
|
||||
--- core/html/parser/HTMLConstructionSite.cpp
|
||||
+++ core/html/parser/HTMLConstructionSite.cpp
|
||||
@@ -50,7 +50,6 @@
|
||||
#include "core/loader/FrameLoaderClient.h"
|
||||
#include "core/svg/SVGScriptElement.h"
|
||||
#include "platform/NotImplemented.h"
|
||||
-#include "platform/ScriptForbiddenScope.h"
|
||||
#include "platform/text/TextBreakIterator.h"
|
||||
#include <limits>
|
||||
|
||||
@@ -103,10 +102,8 @@ static inline void insert(HTMLConstructionSiteTask& task)
|
||||
if (isHTMLTemplateElement(*task.parent))
|
||||
task.parent = toHTMLTemplateElement(task.parent.get())->content();
|
||||
|
||||
- if (ContainerNode* parent = task.child->parentNode()) {
|
||||
- ScriptForbiddenScope forbidScript;
|
||||
+ if (ContainerNode* parent = task.child->parentNode())
|
||||
parent->parserRemoveChild(*task.child);
|
||||
- }
|
||||
|
||||
if (task.nextChild)
|
||||
task.parent->parserInsertBefore(task.child.get(), *task.nextChild);
|
||||
@@ -153,10 +150,8 @@ static inline void executeReparentTask(HTMLConstructionSiteTask& task)
|
||||
{
|
||||
ASSERT(task.operation == HTMLConstructionSiteTask::Reparent);
|
||||
|
||||
- if (ContainerNode* parent = task.child->parentNode()) {
|
||||
- ScriptForbiddenScope forbidScript;
|
||||
+ if (ContainerNode* parent = task.child->parentNode())
|
||||
parent->parserRemoveChild(*task.child);
|
||||
- }
|
||||
|
||||
task.parent->parserAppendChild(task.child);
|
||||
}
|
@@ -12,7 +12,7 @@ index 606a744..4003e49 100644
|
||||
|
||||
if (RuntimeEnabledFeatures::htmlPopupMenuEnabled() && RuntimeEnabledFeatures::pagePopupEnabled())
|
||||
diff --git Source/web/WebViewImpl.cpp Source/web/WebViewImpl.cpp
|
||||
index aa9c0c5..9f14208 100644
|
||||
index 8ab4888..17428a5 100644
|
||||
--- Source/web/WebViewImpl.cpp
|
||||
+++ Source/web/WebViewImpl.cpp
|
||||
@@ -396,6 +396,7 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
|
||||
@@ -23,7 +23,7 @@ index aa9c0c5..9f14208 100644
|
||||
, m_doingDragAndDrop(false)
|
||||
, m_ignoreInputEvents(false)
|
||||
, m_compositorDeviceScaleFactorOverride(0)
|
||||
@@ -4036,9 +4037,14 @@ void WebViewImpl::pageScaleFactorChanged()
|
||||
@@ -4044,9 +4045,14 @@ void WebViewImpl::pageScaleFactorChanged()
|
||||
m_client->pageScaleFactorChanged();
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ index aa9c0c5..9f14208 100644
|
||||
|
||||
void WebViewImpl::startDragging(LocalFrame* frame,
|
||||
diff --git Source/web/WebViewImpl.h Source/web/WebViewImpl.h
|
||||
index cf3f40e..f6acc16 100644
|
||||
index 3bba907..07f8c99 100644
|
||||
--- Source/web/WebViewImpl.h
|
||||
+++ Source/web/WebViewImpl.h
|
||||
@@ -394,7 +394,8 @@ public:
|
||||
@@ -53,7 +53,7 @@ index cf3f40e..f6acc16 100644
|
||||
|
||||
bool contextMenuAllowed() const
|
||||
{
|
||||
@@ -688,6 +689,8 @@ private:
|
||||
@@ -690,6 +691,8 @@ private:
|
||||
|
||||
bool m_contextMenuAllowed;
|
||||
|
||||
|
@@ -68,4 +68,10 @@ void BrowserWindow::OnSetLoadingState(bool isLoading,
|
||||
delegate_->OnSetLoadingState(isLoading, canGoBack, canGoForward);
|
||||
}
|
||||
|
||||
void BrowserWindow::OnSetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
delegate_->OnSetDraggableRegions(regions);
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
|
@@ -39,6 +39,10 @@ class BrowserWindow : public ClientHandler::Delegate {
|
||||
bool canGoBack,
|
||||
bool canGoForward) = 0;
|
||||
|
||||
// Set the draggable regions.
|
||||
virtual void OnSetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Delegate() {}
|
||||
};
|
||||
@@ -101,6 +105,8 @@ class BrowserWindow : public ClientHandler::Delegate {
|
||||
void OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) OVERRIDE;
|
||||
void OnSetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) OVERRIDE;
|
||||
|
||||
Delegate* delegate_;
|
||||
CefRefPtr<CefBrowser> browser_;
|
||||
|
@@ -667,7 +667,8 @@ BrowserOpenGLView* GLView(NSView* view) {
|
||||
// Fill with the background color.
|
||||
const cef_color_t background_color = renderer_->GetBackgroundColor();
|
||||
NSColor* color =
|
||||
[NSColor colorWithRed:float(CefColorGetR(background_color)) / 255.0f
|
||||
[NSColor colorWithCalibratedRed:
|
||||
float(CefColorGetR(background_color)) / 255.0f
|
||||
green:float(CefColorGetG(background_color)) / 255.0f
|
||||
blue:float(CefColorGetB(background_color)) / 255.0f
|
||||
alpha:1.f];
|
||||
|
@@ -121,6 +121,9 @@ ClientHandler::ClientHandler(Delegate* delegate,
|
||||
dialog_handler_ = new ClientDialogHandlerGtk();
|
||||
#endif
|
||||
|
||||
resource_manager_ = new CefResourceManager();
|
||||
test_runner::SetupResourceManager(resource_manager_);
|
||||
|
||||
// Read command line settings.
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
@@ -290,6 +293,14 @@ bool ClientHandler::OnDragEnter(CefRefPtr<CefBrowser> browser,
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClientHandler::OnDraggableRegionsChanged(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
const std::vector<CefDraggableRegion>& regions) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
NotifyDraggableRegions(regions);
|
||||
}
|
||||
|
||||
bool ClientHandler::OnRequestGeolocationPermission(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
const CefString& requesting_url,
|
||||
@@ -453,13 +464,24 @@ bool ClientHandler::OnOpenURLFromTab(
|
||||
return false;
|
||||
}
|
||||
|
||||
cef_return_value_t ClientHandler::OnBeforeResourceLoad(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefRequestCallback> callback) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
return resource_manager_->OnBeforeResourceLoad(browser, frame, request,
|
||||
callback);
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> ClientHandler::GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
return test_runner::GetResourceHandler(browser, frame, request);
|
||||
return resource_manager_->GetResourceHandler(browser, frame, request);
|
||||
}
|
||||
|
||||
bool ClientHandler::OnQuotaRequest(CefRefPtr<CefBrowser> browser,
|
||||
@@ -676,6 +698,19 @@ void ClientHandler::NotifyLoadingState(bool isLoading,
|
||||
delegate_->OnSetLoadingState(isLoading, canGoBack, canGoForward);
|
||||
}
|
||||
|
||||
void ClientHandler::NotifyDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) {
|
||||
if (!CURRENTLY_ON_MAIN_THREAD()) {
|
||||
// Execute this method on the main thread.
|
||||
MAIN_POST_CLOSURE(
|
||||
base::Bind(&ClientHandler::NotifyDraggableRegions, this, regions));
|
||||
return;
|
||||
}
|
||||
|
||||
if (delegate_)
|
||||
delegate_->OnSetDraggableRegions(regions);
|
||||
}
|
||||
|
||||
void ClientHandler::BuildTestMenu(CefRefPtr<CefMenuModel> model) {
|
||||
if (model->GetCount() > 0)
|
||||
model->AddSeparator();
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include "include/cef_client.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
#include "include/wrapper/cef_message_router.h"
|
||||
#include "include/wrapper/cef_resource_manager.h"
|
||||
#include "cefclient/browser/client_types.h"
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
@@ -57,6 +58,10 @@ class ClientHandler : public CefClient,
|
||||
bool canGoBack,
|
||||
bool canGoForward) = 0;
|
||||
|
||||
// Set the draggable regions.
|
||||
virtual void OnSetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Delegate() {}
|
||||
};
|
||||
@@ -152,6 +157,10 @@ class ClientHandler : public CefClient,
|
||||
CefRefPtr<CefDragData> dragData,
|
||||
CefDragHandler::DragOperationsMask mask) OVERRIDE;
|
||||
|
||||
void OnDraggableRegionsChanged(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
const std::vector<CefDraggableRegion>& regions) OVERRIDE;
|
||||
|
||||
// CefGeolocationHandler methods
|
||||
bool OnRequestGeolocationPermission(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
@@ -204,6 +213,11 @@ class ClientHandler : public CefClient,
|
||||
const CefString& target_url,
|
||||
CefRequestHandler::WindowOpenDisposition target_disposition,
|
||||
bool user_gesture) OVERRIDE;
|
||||
cef_return_value_t OnBeforeResourceLoad(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefRequestCallback> callback) OVERRIDE;
|
||||
CefRefPtr<CefResourceHandler> GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
@@ -263,6 +277,8 @@ class ClientHandler : public CefClient,
|
||||
void NotifyLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward);
|
||||
void NotifyDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions);
|
||||
|
||||
// Test context menu creation.
|
||||
void BuildTestMenu(CefRefPtr<CefMenuModel> model);
|
||||
@@ -288,7 +304,10 @@ class ClientHandler : public CefClient,
|
||||
// Handles the browser side of query routing. The renderer side is handled
|
||||
// in client_renderer.cc.
|
||||
CefRefPtr<CefMessageRouterBrowserSide> message_router_;
|
||||
|
||||
|
||||
// Manages the registration and delivery of resources.
|
||||
CefRefPtr<CefResourceManager> resource_manager_;
|
||||
|
||||
// MAIN THREAD MEMBERS
|
||||
// The following members will only be accessed on the main thread. This will
|
||||
// be the same as the CEF UI thread except when using multi-threaded message
|
||||
|
@@ -443,6 +443,8 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
LONG currentTime = 0;
|
||||
bool cancelPreviousClick = false;
|
||||
|
||||
const float device_scale_factor = GetDeviceScaleFactor();
|
||||
|
||||
if (message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN ||
|
||||
message == WM_MBUTTONDOWN || message == WM_MOUSEMOVE ||
|
||||
message == WM_MOUSELEAVE) {
|
||||
@@ -496,6 +498,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
mouse_event.y = y;
|
||||
last_mouse_down_on_view_ = !IsOverPopupWidget(x, y);
|
||||
ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
DeviceToLogical(mouse_event, device_scale_factor);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
browser_host->SendMouseClickEvent(mouse_event, btnType, false,
|
||||
last_click_count_);
|
||||
@@ -529,6 +532,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
break;
|
||||
}
|
||||
ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
DeviceToLogical(mouse_event, device_scale_factor);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
browser_host->SendMouseClickEvent(mouse_event, btnType, true,
|
||||
last_click_count_);
|
||||
@@ -566,6 +570,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
mouse_event.x = x;
|
||||
mouse_event.y = y;
|
||||
ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
DeviceToLogical(mouse_event, device_scale_factor);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
browser_host->SendMouseMoveEvent(mouse_event, false);
|
||||
}
|
||||
@@ -593,6 +598,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
CefMouseEvent mouse_event;
|
||||
mouse_event.x = p.x;
|
||||
mouse_event.y = p.y;
|
||||
DeviceToLogical(mouse_event, device_scale_factor);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
browser_host->SendMouseMoveEvent(mouse_event, true);
|
||||
}
|
||||
@@ -612,8 +618,8 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
mouse_event.x = screen_point.x;
|
||||
mouse_event.y = screen_point.y;
|
||||
ApplyPopupOffset(mouse_event.x, mouse_event.y);
|
||||
DeviceToLogical(mouse_event, device_scale_factor);
|
||||
mouse_event.modifiers = GetCefMouseModifiers(wParam);
|
||||
|
||||
browser_host->SendMouseWheelEvent(mouse_event,
|
||||
IsKeyDown(VK_SHIFT) ? delta : 0,
|
||||
!IsKeyDown(VK_SHIFT) ? delta : 0);
|
||||
@@ -731,16 +737,6 @@ void OsrWindowWin::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||
bool OsrWindowWin::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
RECT window_rect = {0};
|
||||
HWND root_window = GetAncestor(hwnd_, GA_ROOT);
|
||||
if (::GetWindowRect(root_window, &window_rect)) {
|
||||
rect = CefRect(window_rect.left,
|
||||
window_rect.top,
|
||||
window_rect.right - window_rect.left,
|
||||
window_rect.bottom - window_rect.top);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -748,9 +744,13 @@ bool OsrWindowWin::GetViewRect(CefRefPtr<CefBrowser> browser,
|
||||
CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
rect.x = rect.y = 0;
|
||||
rect.width = client_rect_.right - client_rect_.left;
|
||||
rect.height = client_rect_.bottom - client_rect_.top;
|
||||
const float device_scale_factor = GetDeviceScaleFactor();
|
||||
|
||||
rect.x = rect.y = 0;
|
||||
rect.width = DeviceToLogical(client_rect_.right - client_rect_.left,
|
||||
device_scale_factor);
|
||||
rect.height = DeviceToLogical(client_rect_.bottom - client_rect_.top,
|
||||
device_scale_factor);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -764,8 +764,13 @@ bool OsrWindowWin::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||
if (!::IsWindow(hwnd_))
|
||||
return false;
|
||||
|
||||
const float device_scale_factor = GetDeviceScaleFactor();
|
||||
|
||||
// Convert the point from view coordinates to actual screen coordinates.
|
||||
POINT screen_pt = {viewX, viewY};
|
||||
POINT screen_pt = {
|
||||
LogicalToDevice(viewX, device_scale_factor),
|
||||
LogicalToDevice(viewY, device_scale_factor)
|
||||
};
|
||||
ClientToScreen(hwnd_, &screen_pt);
|
||||
screenX = screen_pt.x;
|
||||
screenY = screen_pt.y;
|
||||
@@ -776,7 +781,19 @@ bool OsrWindowWin::GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||
CefScreenInfo& screen_info) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
return false;
|
||||
if (!::IsWindow(hwnd_))
|
||||
return false;
|
||||
|
||||
CefRect view_rect;
|
||||
GetViewRect(browser, view_rect);
|
||||
|
||||
screen_info.device_scale_factor = GetDeviceScaleFactor();
|
||||
|
||||
// The screen info rectangles are used by the renderer to create and position
|
||||
// popups. Keep popups inside the view rectangle.
|
||||
screen_info.rect = view_rect;
|
||||
screen_info.available_rect = view_rect;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
||||
@@ -794,7 +811,7 @@ void OsrWindowWin::OnPopupSize(CefRefPtr<CefBrowser> browser,
|
||||
const CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
renderer_.OnPopupSize(browser, rect);
|
||||
renderer_.OnPopupSize(browser, LogicalToDevice(rect, GetDeviceScaleFactor()));
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnPaint(CefRefPtr<CefBrowser> browser,
|
||||
@@ -848,6 +865,7 @@ bool OsrWindowWin::StartDragging(
|
||||
#if defined(CEF_USE_ATL)
|
||||
if (!drop_target_)
|
||||
return false;
|
||||
|
||||
current_drag_op_ = DRAG_OPERATION_NONE;
|
||||
CefBrowserHost::DragOperationsMask result =
|
||||
drop_target_->StartDragging(browser, drag_data, allowed_ops, x, y);
|
||||
@@ -855,7 +873,13 @@ bool OsrWindowWin::StartDragging(
|
||||
POINT pt = {};
|
||||
GetCursorPos(&pt);
|
||||
ScreenToClient(hwnd_, &pt);
|
||||
browser->GetHost()->DragSourceEndedAt(pt.x, pt.y, result);
|
||||
|
||||
const float device_scale_factor = GetDeviceScaleFactor();
|
||||
|
||||
browser->GetHost()->DragSourceEndedAt(
|
||||
DeviceToLogical(pt.x, device_scale_factor),
|
||||
DeviceToLogical(pt.y, device_scale_factor),
|
||||
result);
|
||||
browser->GetHost()->DragSourceSystemDragEnded();
|
||||
return true;
|
||||
#else
|
||||
@@ -881,6 +905,7 @@ OsrWindowWin::OnDragEnter(CefRefPtr<CefDragData> drag_data,
|
||||
CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) {
|
||||
if (browser_) {
|
||||
DeviceToLogical(ev, GetDeviceScaleFactor());
|
||||
browser_->GetHost()->DragTargetDragEnter(drag_data, ev, effect);
|
||||
browser_->GetHost()->DragTargetDragOver(ev, effect);
|
||||
}
|
||||
@@ -890,8 +915,10 @@ OsrWindowWin::OnDragEnter(CefRefPtr<CefDragData> drag_data,
|
||||
CefBrowserHost::DragOperationsMask
|
||||
OsrWindowWin::OnDragOver(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) {
|
||||
if (browser_)
|
||||
if (browser_) {
|
||||
DeviceToLogical(ev, GetDeviceScaleFactor());
|
||||
browser_->GetHost()->DragTargetDragOver(ev, effect);
|
||||
}
|
||||
return current_drag_op_;
|
||||
}
|
||||
|
||||
@@ -904,6 +931,7 @@ CefBrowserHost::DragOperationsMask
|
||||
OsrWindowWin::OnDrop(CefMouseEvent ev,
|
||||
CefBrowserHost::DragOperationsMask effect) {
|
||||
if (browser_) {
|
||||
DeviceToLogical(ev, GetDeviceScaleFactor());
|
||||
browser_->GetHost()->DragTargetDragOver(ev, effect);
|
||||
browser_->GetHost()->DragTargetDrop(ev);
|
||||
}
|
||||
|
@@ -9,6 +9,10 @@
|
||||
#include <string>
|
||||
#include "include/cef_stream.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "include/wrapper/cef_resource_manager.h"
|
||||
#endif
|
||||
|
||||
namespace client {
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
@@ -22,6 +26,12 @@ bool LoadBinaryResource(const char* resource_name, std::string& resource_data);
|
||||
// Retrieve a resource as a steam reader.
|
||||
CefRefPtr<CefStreamReader> GetBinaryResourceReader(const char* resource_name);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Create a new provider for loading binary resources.
|
||||
CefResourceManager::Provider* CreateBinaryResourceProvider(
|
||||
const std::string& url_path);
|
||||
#endif
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_RESOURCE_UTIL_H_
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/cef_stream.h"
|
||||
#include "include/wrapper/cef_byte_read_handler.h"
|
||||
#include "include/wrapper/cef_stream_resource_handler.h"
|
||||
#include "cefclient/browser/resource.h"
|
||||
|
||||
namespace client {
|
||||
@@ -58,6 +59,46 @@ int GetResourceId(const char* resource_name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Provider of binary resources.
|
||||
class BinaryResourceProvider : public CefResourceManager::Provider {
|
||||
public:
|
||||
explicit BinaryResourceProvider(const std::string& url_path)
|
||||
: url_path_(url_path) {
|
||||
DCHECK(!url_path.empty());
|
||||
}
|
||||
|
||||
bool OnRequest(scoped_refptr<CefResourceManager::Request> request) OVERRIDE {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
const std::string& url = request->url();
|
||||
if (url.find(url_path_) != 0L) {
|
||||
// Not handled by this provider.
|
||||
return false;
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> handler;
|
||||
|
||||
const std::string& relative_path = url.substr(url_path_.length());
|
||||
if (!relative_path.empty()) {
|
||||
CefRefPtr<CefStreamReader> stream =
|
||||
GetBinaryResourceReader(relative_path.data());
|
||||
if (stream.get()) {
|
||||
handler = new CefStreamResourceHandler(
|
||||
request->mime_type_resolver().Run(url),
|
||||
stream);
|
||||
}
|
||||
}
|
||||
|
||||
request->Continue(handler);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string url_path_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(BinaryResourceProvider);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
bool LoadBinaryResource(const char* resource_name, std::string& resource_data) {
|
||||
@@ -94,4 +135,9 @@ CefRefPtr<CefStreamReader> GetBinaryResourceReader(const char* resource_name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CefResourceManager::Provider* CreateBinaryResourceProvider(
|
||||
const std::string& url_path) {
|
||||
return new BinaryResourceProvider(url_path);
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
|
@@ -387,6 +387,12 @@ void RootWindowGtk::OnSetLoadingState(bool isLoading,
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowGtk::OnSetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
// TODO(cef): Implement support for draggable regions on this platform.
|
||||
}
|
||||
|
||||
void RootWindowGtk::NotifyDestroyedIfDone() {
|
||||
// Notify once both the window and the browser have been destroyed.
|
||||
if (window_destroyed_ && browser_destroyed_)
|
||||
|
@@ -58,6 +58,8 @@ class RootWindowGtk : public RootWindow,
|
||||
void OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) OVERRIDE;
|
||||
void OnSetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) OVERRIDE;
|
||||
|
||||
void NotifyDestroyedIfDone();
|
||||
|
||||
|
@@ -64,6 +64,8 @@ class RootWindowMac : public RootWindow,
|
||||
void OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) OVERRIDE;
|
||||
void OnSetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) OVERRIDE;
|
||||
|
||||
void NotifyDestroyedIfDone();
|
||||
|
||||
|
@@ -467,7 +467,8 @@ void RootWindowMac::CreateRootWindow(const CefBrowserSettings& settings) {
|
||||
|
||||
const cef_color_t background_color = MainContext::Get()->GetBackgroundColor();
|
||||
[window_ setBackgroundColor:
|
||||
[NSColor colorWithRed:float(CefColorGetR(background_color)) / 255.0f
|
||||
[NSColor colorWithCalibratedRed:
|
||||
float(CefColorGetR(background_color)) / 255.0f
|
||||
green:float(CefColorGetG(background_color)) / 255.0f
|
||||
blue:float(CefColorGetB(background_color)) / 255.0f
|
||||
alpha:1.f]];
|
||||
@@ -575,6 +576,12 @@ void RootWindowMac::OnSetAddress(const std::string& url) {
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowMac::OnSetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
// TODO(cef): Implement support for draggable regions on this platform.
|
||||
}
|
||||
|
||||
void RootWindowMac::OnSetTitle(const std::string& title) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include "cefclient/browser/root_window_win.h"
|
||||
|
||||
#include "include/base/cef_bind.h"
|
||||
#include "include/base/cef_build.h"
|
||||
#include "include/cef_app.h"
|
||||
#include "cefclient/browser/browser_window_osr_win.h"
|
||||
#include "cefclient/browser/browser_window_std_win.h"
|
||||
@@ -41,6 +42,30 @@ INT_PTR CALLBACK AboutWndProc(HWND hDlg, UINT message,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int GetButtonWidth() {
|
||||
static int button_width = BUTTON_WIDTH;
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized) {
|
||||
button_width = LogicalToDevice(BUTTON_WIDTH, GetDeviceScaleFactor());
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return button_width;
|
||||
}
|
||||
|
||||
int GetURLBarHeight() {
|
||||
static int urlbar_height = URLBAR_HEIGHT;
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized) {
|
||||
urlbar_height = LogicalToDevice(URLBAR_HEIGHT, GetDeviceScaleFactor());
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return urlbar_height;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
RootWindowWin::RootWindowWin()
|
||||
@@ -50,6 +75,8 @@ RootWindowWin::RootWindowWin()
|
||||
start_rect_(),
|
||||
initialized_(false),
|
||||
hwnd_(NULL),
|
||||
draggable_region_(NULL),
|
||||
font_(NULL),
|
||||
back_hwnd_(NULL),
|
||||
forward_hwnd_(NULL),
|
||||
reload_hwnd_(NULL),
|
||||
@@ -65,11 +92,17 @@ RootWindowWin::RootWindowWin()
|
||||
window_destroyed_(false),
|
||||
browser_destroyed_(false) {
|
||||
find_buff_[0] = 0;
|
||||
|
||||
// Create a HRGN representing the draggable window area.
|
||||
draggable_region_ = ::CreateRectRgn(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
RootWindowWin::~RootWindowWin() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
::DeleteObject(draggable_region_);
|
||||
::DeleteObject(font_);
|
||||
|
||||
// The window and browser should already have been destroyed.
|
||||
DCHECK(window_destroyed_);
|
||||
DCHECK(browser_destroyed_);
|
||||
@@ -171,8 +204,11 @@ void RootWindowWin::Hide() {
|
||||
void RootWindowWin::SetBounds(int x, int y, size_t width, size_t height) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
if (hwnd_)
|
||||
SetWindowPos(hwnd_, NULL, 0, 0, 0, 0, SWP_NOZORDER);
|
||||
if (hwnd_) {
|
||||
SetWindowPos(hwnd_, NULL,
|
||||
x, y, static_cast<int>(width), static_cast<int>(height),
|
||||
SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowWin::Close(bool force) {
|
||||
@@ -244,7 +280,7 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) {
|
||||
RECT window_rect = start_rect_;
|
||||
::AdjustWindowRectEx(&window_rect, dwStyle, with_controls_, 0);
|
||||
if (with_controls_)
|
||||
window_rect.bottom += URLBAR_HEIGHT;
|
||||
window_rect.bottom += GetURLBarHeight();
|
||||
|
||||
x = start_rect_.left;
|
||||
y = start_rect_.top;
|
||||
@@ -269,44 +305,61 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) {
|
||||
// Create the child controls.
|
||||
int x = 0;
|
||||
|
||||
static int button_width = GetButtonWidth();
|
||||
static int urlbar_height = GetURLBarHeight();
|
||||
static int font_height = LogicalToDevice(14, GetDeviceScaleFactor());
|
||||
|
||||
// Create a scaled font.
|
||||
font_ = ::CreateFont(
|
||||
-font_height, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
|
||||
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||
DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Arial");
|
||||
|
||||
back_hwnd_ = CreateWindow(
|
||||
L"BUTTON", L"Back",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
||||
x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
|
||||
x, 0, button_width, urlbar_height,
|
||||
hwnd_, reinterpret_cast<HMENU>(IDC_NAV_BACK), hInstance, 0);
|
||||
CHECK(back_hwnd_);
|
||||
x += BUTTON_WIDTH;
|
||||
SendMessage(back_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_), TRUE);
|
||||
x += button_width;
|
||||
|
||||
forward_hwnd_ = CreateWindow(
|
||||
L"BUTTON", L"Forward",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
||||
x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
|
||||
x, 0, button_width, urlbar_height,
|
||||
hwnd_, reinterpret_cast<HMENU>(IDC_NAV_FORWARD), hInstance, 0);
|
||||
CHECK(forward_hwnd_);
|
||||
x += BUTTON_WIDTH;
|
||||
SendMessage(forward_hwnd_, WM_SETFONT,
|
||||
reinterpret_cast<WPARAM>(font_), TRUE);
|
||||
x += button_width;
|
||||
|
||||
reload_hwnd_ = CreateWindow(
|
||||
L"BUTTON", L"Reload",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON| WS_DISABLED,
|
||||
x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
|
||||
x, 0, button_width, urlbar_height,
|
||||
hwnd_, reinterpret_cast<HMENU>(IDC_NAV_RELOAD), hInstance, 0);
|
||||
CHECK(reload_hwnd_);
|
||||
x += BUTTON_WIDTH;
|
||||
SendMessage(reload_hwnd_, WM_SETFONT,
|
||||
reinterpret_cast<WPARAM>(font_), TRUE);
|
||||
x += button_width;
|
||||
|
||||
stop_hwnd_ = CreateWindow(
|
||||
L"BUTTON", L"Stop",
|
||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
||||
x, 0, BUTTON_WIDTH, URLBAR_HEIGHT,
|
||||
x, 0, button_width, urlbar_height,
|
||||
hwnd_, reinterpret_cast<HMENU>(IDC_NAV_STOP), hInstance, 0);
|
||||
CHECK(stop_hwnd_);
|
||||
x += BUTTON_WIDTH;
|
||||
SendMessage(stop_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_), TRUE);
|
||||
x += button_width;
|
||||
|
||||
edit_hwnd_ = CreateWindow(
|
||||
L"EDIT", 0,
|
||||
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL |
|
||||
ES_AUTOHSCROLL| WS_DISABLED,
|
||||
x, 0, rect.right - BUTTON_WIDTH * 4, URLBAR_HEIGHT,
|
||||
x, 0, rect.right - button_width * 4, urlbar_height,
|
||||
hwnd_, 0, hInstance, 0);
|
||||
SendMessage(edit_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_), TRUE);
|
||||
CHECK(edit_hwnd_);
|
||||
|
||||
// Override the edit control's window procedure.
|
||||
@@ -315,7 +368,7 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) {
|
||||
// Associate |this| with the edit window.
|
||||
SetUserDataPtr(edit_hwnd_, this);
|
||||
|
||||
rect.top += URLBAR_HEIGHT;
|
||||
rect.top += urlbar_height;
|
||||
} else {
|
||||
// No controls so also remove the default menu.
|
||||
::SetMenu(hwnd_, NULL);
|
||||
@@ -498,6 +551,21 @@ LRESULT CALLBACK RootWindowWin::RootWndProc(HWND hWnd, UINT message,
|
||||
return 0; // Cancel the close.
|
||||
break;
|
||||
|
||||
case WM_NCHITTEST: {
|
||||
LRESULT hit = DefWindowProc(hWnd, message, wParam, lParam);
|
||||
if (hit == HTCLIENT) {
|
||||
POINTS points = MAKEPOINTS(lParam);
|
||||
POINT point = { points.x, points.y };
|
||||
::ScreenToClient(hWnd, &point);
|
||||
if (::PtInRegion(self->draggable_region_, point.x, point.y)) {
|
||||
// If cursor is inside a draggable region return HTCAPTION to allow
|
||||
// dragging.
|
||||
return HTCAPTION;
|
||||
}
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
case WM_NCDESTROY:
|
||||
// Clear the reference to |self|.
|
||||
SetUserDataPtr(hWnd, NULL);
|
||||
@@ -535,23 +603,26 @@ void RootWindowWin::OnSize(bool minimized) {
|
||||
GetClientRect(hwnd_, &rect);
|
||||
|
||||
if (with_controls_) {
|
||||
// Resize the window and address bar to match the new frame size.
|
||||
rect.top += URLBAR_HEIGHT;
|
||||
static int button_width = GetButtonWidth();
|
||||
static int urlbar_height = GetURLBarHeight();
|
||||
|
||||
int urloffset = rect.left + BUTTON_WIDTH * 4;
|
||||
// Resize the window and address bar to match the new frame size.
|
||||
rect.top += urlbar_height;
|
||||
|
||||
int urloffset = rect.left + button_width * 4;
|
||||
|
||||
if (browser_window_) {
|
||||
HWND browser_hwnd = browser_window_->GetWindowHandle();
|
||||
HDWP hdwp = BeginDeferWindowPos(1);
|
||||
hdwp = DeferWindowPos(hdwp, edit_hwnd_, NULL, urloffset,
|
||||
0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER);
|
||||
0, rect.right - urloffset, urlbar_height, SWP_NOZORDER);
|
||||
hdwp = DeferWindowPos(hdwp, browser_hwnd, NULL,
|
||||
rect.left, rect.top, rect.right - rect.left,
|
||||
rect.bottom - rect.top, SWP_NOZORDER);
|
||||
EndDeferWindowPos(hdwp);
|
||||
} else {
|
||||
SetWindowPos(edit_hwnd_, NULL, urloffset,
|
||||
0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER);
|
||||
0, rect.right - urloffset, urlbar_height, SWP_NOZORDER);
|
||||
}
|
||||
} else if (browser_window_) {
|
||||
// Size the browser window to the whole client area.
|
||||
@@ -749,6 +820,111 @@ void RootWindowWin::OnSetLoadingState(bool isLoading,
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
LPCWSTR kParentWndProc = L"CefParentWndProc";
|
||||
LPCWSTR kDraggableRegion = L"CefDraggableRegion";
|
||||
|
||||
LRESULT CALLBACK SubclassedWindowProc(
|
||||
HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
WNDPROC hParentWndProc = reinterpret_cast<WNDPROC>(
|
||||
::GetPropW(hWnd, kParentWndProc));
|
||||
HRGN hRegion = reinterpret_cast<HRGN>(
|
||||
::GetPropW(hWnd, kDraggableRegion));
|
||||
|
||||
if (message == WM_NCHITTEST) {
|
||||
LRESULT hit = CallWindowProc(
|
||||
hParentWndProc, hWnd, message, wParam, lParam);
|
||||
if (hit == HTCLIENT) {
|
||||
POINTS points = MAKEPOINTS(lParam);
|
||||
POINT point = { points.x, points.y };
|
||||
::ScreenToClient(hWnd, &point);
|
||||
if (::PtInRegion(hRegion, point.x, point.y)) {
|
||||
// Let the parent window handle WM_NCHITTEST by returning HTTRANSPARENT
|
||||
// in child windows.
|
||||
return HTTRANSPARENT;
|
||||
}
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
return CallWindowProc(hParentWndProc, hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
void SubclassWindow(HWND hWnd, HRGN hRegion) {
|
||||
HANDLE hParentWndProc = ::GetPropW(hWnd, kParentWndProc);
|
||||
if (hParentWndProc) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetLastError(0);
|
||||
LONG_PTR hOldWndProc = SetWindowLongPtr(
|
||||
hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SubclassedWindowProc));
|
||||
if (hOldWndProc == 0 && GetLastError() != ERROR_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
::SetPropW(hWnd, kParentWndProc, reinterpret_cast<HANDLE>(hOldWndProc));
|
||||
::SetPropW(hWnd, kDraggableRegion, reinterpret_cast<HANDLE>(hRegion));
|
||||
}
|
||||
|
||||
void UnSubclassWindow(HWND hWnd) {
|
||||
LONG_PTR hParentWndProc = reinterpret_cast<LONG_PTR>(
|
||||
::GetPropW(hWnd, kParentWndProc));
|
||||
if (hParentWndProc) {
|
||||
LONG_PTR hPreviousWndProc =
|
||||
SetWindowLongPtr(hWnd, GWLP_WNDPROC, hParentWndProc);
|
||||
ALLOW_UNUSED_LOCAL(hPreviousWndProc);
|
||||
DCHECK_EQ(hPreviousWndProc,
|
||||
reinterpret_cast<LONG_PTR>(SubclassedWindowProc));
|
||||
}
|
||||
|
||||
::RemovePropW(hWnd, kParentWndProc);
|
||||
::RemovePropW(hWnd, kDraggableRegion);
|
||||
}
|
||||
|
||||
BOOL CALLBACK SubclassWindowsProc(HWND hwnd, LPARAM lParam) {
|
||||
SubclassWindow(hwnd, reinterpret_cast<HRGN>(lParam));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CALLBACK UnSubclassWindowsProc(HWND hwnd, LPARAM lParam) {
|
||||
UnSubclassWindow(hwnd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void RootWindowWin::OnSetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
||||
// Reset draggable region.
|
||||
::SetRectRgn(draggable_region_, 0, 0, 0, 0);
|
||||
|
||||
// Determine new draggable region.
|
||||
std::vector<CefDraggableRegion>::const_iterator it = regions.begin();
|
||||
for (;it != regions.end(); ++it) {
|
||||
HRGN region = ::CreateRectRgn(
|
||||
it->bounds.x, it->bounds.y,
|
||||
it->bounds.x + it->bounds.width,
|
||||
it->bounds.y + it->bounds.height);
|
||||
::CombineRgn(
|
||||
draggable_region_, draggable_region_, region,
|
||||
it->draggable ? RGN_OR : RGN_DIFF);
|
||||
::DeleteObject(region);
|
||||
}
|
||||
|
||||
// Subclass child window procedures in order to do hit-testing.
|
||||
// This will be a no-op, if it is already subclassed.
|
||||
if (hwnd_) {
|
||||
WNDENUMPROC proc = !regions.empty() ?
|
||||
SubclassWindowsProc : UnSubclassWindowsProc;
|
||||
::EnumChildWindows(
|
||||
hwnd_, proc, reinterpret_cast<LPARAM>(draggable_region_));
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowWin::NotifyDestroyedIfDone() {
|
||||
// Notify once both the window and the browser have been destroyed.
|
||||
if (window_destroyed_ && browser_destroyed_)
|
||||
|
@@ -90,6 +90,8 @@ class RootWindowWin : public RootWindow,
|
||||
void OnSetLoadingState(bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) OVERRIDE;
|
||||
void OnSetDraggableRegions(
|
||||
const std::vector<CefDraggableRegion>& regions) OVERRIDE;
|
||||
|
||||
void NotifyDestroyedIfDone();
|
||||
|
||||
@@ -105,6 +107,12 @@ class RootWindowWin : public RootWindow,
|
||||
// Main window.
|
||||
HWND hwnd_;
|
||||
|
||||
// Draggable region.
|
||||
HRGN draggable_region_;
|
||||
|
||||
// Font for buttons and text fields.
|
||||
HFONT font_;
|
||||
|
||||
// Buttons.
|
||||
HWND back_hwnd_;
|
||||
HWND forward_hwnd_;
|
||||
@@ -114,7 +122,7 @@ class RootWindowWin : public RootWindow,
|
||||
// URL text field.
|
||||
HWND edit_hwnd_;
|
||||
WNDPROC edit_wndproc_old_;
|
||||
|
||||
|
||||
// Find dialog.
|
||||
HWND find_hwnd_;
|
||||
UINT find_message_id_;
|
||||
|
@@ -243,45 +243,75 @@ void RunOtherTests(CefRefPtr<CefBrowser> browser) {
|
||||
browser->GetMainFrame()->LoadURL("http://tests/other_tests");
|
||||
}
|
||||
|
||||
// Retrieve the file name and mime type based on the specified url.
|
||||
bool ParseTestUrl(const std::string& url,
|
||||
std::string* file_name,
|
||||
std::string* mime_type) {
|
||||
// Retrieve the path component.
|
||||
CefURLParts parts;
|
||||
CefParseURL(url, parts);
|
||||
std::string file = CefString(&parts.path);
|
||||
if (file.size() < 2)
|
||||
return false;
|
||||
|
||||
// Remove the leading slash.
|
||||
file = file.substr(1);
|
||||
|
||||
// Verify that the file name is valid.
|
||||
for(size_t i = 0; i < file.size(); ++i) {
|
||||
const char c = file[i];
|
||||
if (!isalpha(c) && !isdigit(c) && c != '_' && c != '.')
|
||||
return false;
|
||||
// Provider that dumps the request contents.
|
||||
class RequestDumpResourceProvider : public CefResourceManager::Provider {
|
||||
public:
|
||||
explicit RequestDumpResourceProvider(const std::string& url)
|
||||
: url_(url) {
|
||||
DCHECK(!url.empty());
|
||||
}
|
||||
|
||||
// Determine the mime type based on the file extension, if any.
|
||||
size_t pos = file.rfind(".");
|
||||
if (pos != std::string::npos) {
|
||||
std::string ext = file.substr(pos + 1);
|
||||
if (ext == "html")
|
||||
*mime_type = "text/html";
|
||||
else if (ext == "png")
|
||||
*mime_type = "image/png";
|
||||
else
|
||||
bool OnRequest(scoped_refptr<CefResourceManager::Request> request) OVERRIDE {
|
||||
CEF_REQUIRE_IO_THREAD();
|
||||
|
||||
const std::string& url = request->url();
|
||||
if (url != url_) {
|
||||
// Not handled by this provider.
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& dump = DumpRequestContents(request->request());
|
||||
std::string str = "<html><body bgcolor=\"white\"><pre>" + dump +
|
||||
"</pre></body></html>";
|
||||
CefRefPtr<CefStreamReader> stream =
|
||||
CefStreamReader::CreateForData(
|
||||
static_cast<void*>(const_cast<char*>(str.c_str())),
|
||||
str.size());
|
||||
DCHECK(stream.get());
|
||||
request->Continue(new CefStreamResourceHandler("text/html", stream));
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string url_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RequestDumpResourceProvider);
|
||||
};
|
||||
|
||||
// Add a file extension to |url| if none is currently specified.
|
||||
std::string RequestUrlFilter(const std::string& url) {
|
||||
if (url.find(kTestOrigin) != 0U) {
|
||||
// Don't filter anything outside of the test origin.
|
||||
return url;
|
||||
}
|
||||
|
||||
// Identify where the query or fragment component, if any, begins.
|
||||
size_t suffix_pos = url.find('?');
|
||||
if (suffix_pos == std::string::npos)
|
||||
suffix_pos = url.find('#');
|
||||
|
||||
std::string url_base, url_suffix;
|
||||
if (suffix_pos == std::string::npos) {
|
||||
url_base = url;
|
||||
} else {
|
||||
// Default to an html extension if none is specified.
|
||||
*mime_type = "text/html";
|
||||
file += ".html";
|
||||
url_base = url.substr(0, suffix_pos);
|
||||
url_suffix = url.substr(suffix_pos);
|
||||
}
|
||||
|
||||
*file_name = file;
|
||||
return true;
|
||||
// Identify the last path component.
|
||||
size_t path_pos = url_base.rfind('/');
|
||||
if (path_pos == std::string::npos)
|
||||
return url;
|
||||
|
||||
const std::string& path_component = url_base.substr(path_pos);
|
||||
|
||||
// Identify if a file extension is currently specified.
|
||||
size_t ext_pos = path_component.rfind(".");
|
||||
if (ext_pos != std::string::npos)
|
||||
return url;
|
||||
|
||||
// Rebuild the URL with a file extension.
|
||||
return url_base + ".html" + url_suffix;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -448,37 +478,30 @@ std::string GetErrorString(cef_errorcode_t code) {
|
||||
}
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) {
|
||||
std::string url = request->GetURL();
|
||||
if (url.find(kTestOrigin) == 0) {
|
||||
// Handle URLs in the test origin.
|
||||
std::string file_name, mime_type;
|
||||
if (ParseTestUrl(url, &file_name, &mime_type)) {
|
||||
if (file_name == "request.html") {
|
||||
// Show the request contents.
|
||||
const std::string& dump = DumpRequestContents(request);
|
||||
std::string str = "<html><body bgcolor=\"white\"><pre>" + dump +
|
||||
"</pre></body></html>";
|
||||
CefRefPtr<CefStreamReader> stream =
|
||||
CefStreamReader::CreateForData(
|
||||
static_cast<void*>(const_cast<char*>(str.c_str())),
|
||||
str.size());
|
||||
DCHECK(stream.get());
|
||||
return new CefStreamResourceHandler("text/html", stream);
|
||||
} else {
|
||||
// Load the resource from file.
|
||||
CefRefPtr<CefStreamReader> stream =
|
||||
GetBinaryResourceReader(file_name.c_str());
|
||||
if (stream.get())
|
||||
return new CefStreamResourceHandler(mime_type, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
void SetupResourceManager(CefRefPtr<CefResourceManager> resource_manager) {
|
||||
const std::string& test_origin = kTestOrigin;
|
||||
|
||||
return NULL;
|
||||
// Add the URL filter.
|
||||
resource_manager->SetUrlFilter(base::Bind(RequestUrlFilter));
|
||||
|
||||
// Add provider for resource dumps.
|
||||
resource_manager->AddProvider(
|
||||
new RequestDumpResourceProvider(test_origin + "request.html"),
|
||||
0, std::string());
|
||||
|
||||
// Add provider for bundled resource files.
|
||||
#if defined(OS_WIN)
|
||||
// Read resources from the binary.
|
||||
resource_manager->AddProvider(CreateBinaryResourceProvider(test_origin),
|
||||
100, std::string());
|
||||
#elif defined(OS_POSIX)
|
||||
// Read resources from a directory on disk.
|
||||
std::string resource_dir;
|
||||
if (GetResourceDir(resource_dir)) {
|
||||
resource_manager->AddDirectoryProvider(test_origin, resource_dir,
|
||||
100, std::string());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Alert(CefRefPtr<CefBrowser> browser, const std::string& message) {
|
||||
|
@@ -10,9 +10,9 @@
|
||||
#include <string>
|
||||
|
||||
#include "include/cef_browser.h"
|
||||
#include "include/cef_resource_handler.h"
|
||||
#include "include/cef_request.h"
|
||||
#include "include/wrapper/cef_message_router.h"
|
||||
#include "include/wrapper/cef_resource_manager.h"
|
||||
|
||||
namespace client {
|
||||
namespace test_runner {
|
||||
@@ -30,11 +30,8 @@ std::string GetDataURI(const std::string& data,
|
||||
// Returns the string representation of the specified error code.
|
||||
std::string GetErrorString(cef_errorcode_t code);
|
||||
|
||||
// Get test resources.
|
||||
CefRefPtr<CefResourceHandler> GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request);
|
||||
// Set up the resource manager for tests.
|
||||
void SetupResourceManager(CefRefPtr<CefResourceManager> resource_manager);
|
||||
|
||||
// Show a JS alert message.
|
||||
void Alert(CefRefPtr<CefBrowser> browser, const std::string& message);
|
||||
|
@@ -5,7 +5,6 @@
|
||||
#include "cefclient/browser/util_win.h"
|
||||
|
||||
#include "include/base/cef_logging.h"
|
||||
#include "include/internal/cef_types.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
@@ -140,4 +139,51 @@ bool IsKeyDown(WPARAM wparam) {
|
||||
return (GetKeyState(wparam) & 0x8000) != 0;
|
||||
}
|
||||
|
||||
float GetDeviceScaleFactor() {
|
||||
static float scale_factor = 1.0;
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized) {
|
||||
// This value is safe to cache for the life time of the app since the user
|
||||
// must logout to change the DPI setting. This value also applies to all
|
||||
// screens.
|
||||
HDC screen_dc = ::GetDC(NULL);
|
||||
int dpi_x = GetDeviceCaps(screen_dc, LOGPIXELSX);
|
||||
scale_factor = static_cast<float>(dpi_x) / 96.0f;
|
||||
::ReleaseDC(NULL, screen_dc);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return scale_factor;
|
||||
}
|
||||
|
||||
int LogicalToDevice(int value, float device_scale_factor) {
|
||||
float scaled_val = static_cast<float>(value) * device_scale_factor;
|
||||
return static_cast<int>(std::floor(scaled_val));
|
||||
}
|
||||
|
||||
CefRect LogicalToDevice(const CefRect& value, float device_scale_factor) {
|
||||
return CefRect(LogicalToDevice(value.x, device_scale_factor),
|
||||
LogicalToDevice(value.y, device_scale_factor),
|
||||
LogicalToDevice(value.width, device_scale_factor),
|
||||
LogicalToDevice(value.height, device_scale_factor));
|
||||
}
|
||||
|
||||
int DeviceToLogical(int value, float device_scale_factor) {
|
||||
float scaled_val = static_cast<float>(value) / device_scale_factor;
|
||||
return static_cast<int>(std::floor(scaled_val));
|
||||
}
|
||||
|
||||
CefRect DeviceToLogical(const CefRect& value, float device_scale_factor) {
|
||||
return CefRect(DeviceToLogical(value.x, device_scale_factor),
|
||||
DeviceToLogical(value.y, device_scale_factor),
|
||||
DeviceToLogical(value.width, device_scale_factor),
|
||||
DeviceToLogical(value.height, device_scale_factor));
|
||||
}
|
||||
|
||||
void DeviceToLogical(CefMouseEvent& value, float device_scale_factor) {
|
||||
value.x = DeviceToLogical(value.x, device_scale_factor);
|
||||
value.y = DeviceToLogical(value.y, device_scale_factor);
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
|
@@ -9,6 +9,8 @@
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
#include "include/internal/cef_types_wrappers.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
// Set the window's user data pointer.
|
||||
@@ -30,6 +32,19 @@ int GetCefMouseModifiers(WPARAM wparam);
|
||||
int GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam);
|
||||
bool IsKeyDown(WPARAM wparam);
|
||||
|
||||
// Returns the device scale factor. For example, 200% display scaling will
|
||||
// return 2.0.
|
||||
float GetDeviceScaleFactor();
|
||||
|
||||
// Convert |value| from logical coordinates to device coordinates.
|
||||
int LogicalToDevice(int value, float device_scale_factor);
|
||||
CefRect LogicalToDevice(const CefRect& value, float device_scale_factor);
|
||||
|
||||
// Convert |value| from device coordinates to logical coordinates.
|
||||
int DeviceToLogical(int value, float device_scale_factor);
|
||||
CefRect DeviceToLogical(const CefRect& value, float device_scale_factor);
|
||||
void DeviceToLogical(CefMouseEvent& value, float device_scale_factor);
|
||||
|
||||
} // namespace client
|
||||
|
||||
#endif // CEF_TESTS_CEFCLIENT_BROWSER_UTIL_WIN_H_
|
||||
|
@@ -32,6 +32,9 @@ namespace client {
|
||||
namespace {
|
||||
|
||||
int RunMain(HINSTANCE hInstance, int nCmdShow) {
|
||||
// Enable High-DPI support on Windows 7 or newer.
|
||||
CefEnableHighDPISupport();
|
||||
|
||||
CefMainArgs main_args(hInstance);
|
||||
|
||||
void* sandbox_info = NULL;
|
||||
|
@@ -29,6 +29,9 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
|
||||
UNREFERENCED_PARAMETER(hPrevInstance);
|
||||
UNREFERENCED_PARAMETER(lpCmdLine);
|
||||
|
||||
// Enable High-DPI support on Windows 7 or newer.
|
||||
CefEnableHighDPISupport();
|
||||
|
||||
void* sandbox_info = NULL;
|
||||
|
||||
#if defined(CEF_USE_SANDBOX)
|
||||
|
171
tests/unittests/draggable_regions_unittest.cc
Normal file
171
tests/unittests/draggable_regions_unittest.cc
Normal file
@@ -0,0 +1,171 @@
|
||||
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
// Include this first to avoid type conflicts with CEF headers.
|
||||
#include "tests/unittests/chromium_includes.h"
|
||||
|
||||
#include "include/wrapper/cef_closure_task.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "tests/unittests/test_handler.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const char kTestURLWithRegions[] = "http://test.com/regions";
|
||||
const char kTestHTMLWithRegions[] =
|
||||
"<html>"
|
||||
" <body>"
|
||||
" <div style=\"position: absolute; top: 50px; left: 50px; width: 200px; "
|
||||
"height: 200px; background-color: red; -webkit-app-region: drag;\">"
|
||||
" <div style=\"position: absolute; top: 50%; left: 50%; "
|
||||
"transform: translate(-50%, -50%); width: 50px; height: 50px; "
|
||||
"background-color: blue; -webkit-app-region: no-drag;\">"
|
||||
" </div>"
|
||||
" </div>"
|
||||
" </body>"
|
||||
"</html>";
|
||||
|
||||
const char kTestURLWithoutRegions[] = "http://test.com/no-regions";
|
||||
const char kTestHTMLWithoutRegions[] =
|
||||
"<html><body>Hello World!</body></html>";
|
||||
|
||||
const char kTestURLWithChangingRegions[] = "http://test.com/changing-regions";
|
||||
const char kTestHTMLWithChangingRegions[] =
|
||||
"<html>"
|
||||
" <body>"
|
||||
" <div id=\"layer\" style=\"position: absolute; top: 50px; left: 50px; "
|
||||
"width: 200px; height: 200px; background-color: red; "
|
||||
"-webkit-app-region: drag;\">"
|
||||
" <div style=\"position: absolute; top: 50%; left: 50%; "
|
||||
"transform: translate(-50%, -50%); width: 50px; height: 50px; "
|
||||
"background-color: blue; -webkit-app-region: no-drag;\">"
|
||||
" </div>"
|
||||
" </div>"
|
||||
" <script>"
|
||||
" window.setTimeout(function() {"
|
||||
" var layer = document.getElementById('layer');"
|
||||
" layer.style.top = '0px';"
|
||||
" layer.style.left = '0px';"
|
||||
" }, 500);"
|
||||
" </script>"
|
||||
" </body>"
|
||||
"</html>";
|
||||
|
||||
class DraggableRegionsTestHandler : public TestHandler {
|
||||
public:
|
||||
DraggableRegionsTestHandler()
|
||||
: step_(kStepWithRegions) {}
|
||||
|
||||
void RunTest() override {
|
||||
// Add HTML documents with and without draggable regions.
|
||||
AddResource(kTestURLWithRegions, kTestHTMLWithRegions, "text/html");
|
||||
AddResource(kTestURLWithoutRegions, kTestHTMLWithoutRegions, "text/html");
|
||||
AddResource(kTestURLWithChangingRegions, kTestHTMLWithChangingRegions,
|
||||
"text/html");
|
||||
|
||||
// Create the browser
|
||||
CreateBrowser(kTestURLWithRegions);
|
||||
|
||||
// Time out the test after a reasonable period of time.
|
||||
SetTestTimeout();
|
||||
}
|
||||
|
||||
void OnDraggableRegionsChanged(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
const std::vector<CefDraggableRegion>& regions) override {
|
||||
EXPECT_TRUE(CefCurrentlyOn(TID_UI));
|
||||
EXPECT_TRUE(browser->IsSame(GetBrowser()));
|
||||
|
||||
did_call_on_draggable_regions_changed_.yes();
|
||||
|
||||
switch (step_) {
|
||||
case kStepWithRegions:
|
||||
case kStepWithChangingRegions1:
|
||||
EXPECT_EQ(2U, regions.size());
|
||||
EXPECT_EQ(50, regions[0].bounds.x);
|
||||
EXPECT_EQ(50, regions[0].bounds.y);
|
||||
EXPECT_EQ(200, regions[0].bounds.width);
|
||||
EXPECT_EQ(200, regions[0].bounds.height);
|
||||
EXPECT_EQ(1, regions[0].draggable);
|
||||
EXPECT_EQ(125, regions[1].bounds.x);
|
||||
EXPECT_EQ(125, regions[1].bounds.y);
|
||||
EXPECT_EQ(50, regions[1].bounds.width);
|
||||
EXPECT_EQ(50, regions[1].bounds.height);
|
||||
EXPECT_EQ(0, regions[1].draggable);
|
||||
break;
|
||||
case kStepWithChangingRegions2:
|
||||
EXPECT_EQ(2U, regions.size());
|
||||
EXPECT_EQ(0, regions[0].bounds.x);
|
||||
EXPECT_EQ(0, regions[0].bounds.y);
|
||||
EXPECT_EQ(200, regions[0].bounds.width);
|
||||
EXPECT_EQ(200, regions[0].bounds.height);
|
||||
EXPECT_EQ(1, regions[0].draggable);
|
||||
EXPECT_EQ(75, regions[1].bounds.x);
|
||||
EXPECT_EQ(75, regions[1].bounds.y);
|
||||
EXPECT_EQ(50, regions[1].bounds.width);
|
||||
EXPECT_EQ(50, regions[1].bounds.height);
|
||||
EXPECT_EQ(0, regions[1].draggable);
|
||||
break;
|
||||
case kStepWithoutRegions:
|
||||
// Should not be reached.
|
||||
EXPECT_TRUE(false);
|
||||
break;
|
||||
}
|
||||
|
||||
NextTest(browser);
|
||||
}
|
||||
|
||||
void DestroyTest() override {
|
||||
EXPECT_EQ(false, did_call_on_draggable_regions_changed_);
|
||||
|
||||
TestHandler::DestroyTest();
|
||||
}
|
||||
|
||||
private:
|
||||
void NextTest(CefRefPtr<CefBrowser> browser) {
|
||||
CefRefPtr<CefFrame> frame(browser->GetMainFrame());
|
||||
|
||||
did_call_on_draggable_regions_changed_.reset();
|
||||
|
||||
switch (step_) {
|
||||
case kStepWithRegions:
|
||||
step_ = kStepWithChangingRegions1;
|
||||
frame->LoadURL(kTestURLWithChangingRegions);
|
||||
break;
|
||||
case kStepWithChangingRegions1:
|
||||
step_ = kStepWithChangingRegions2;
|
||||
break;
|
||||
case kStepWithChangingRegions2:
|
||||
step_ = kStepWithoutRegions;
|
||||
frame->LoadURL(kTestURLWithoutRegions);
|
||||
// Needed because this test doesn't call OnDraggableRegionsChanged.
|
||||
CefPostDelayedTask(TID_UI,
|
||||
base::Bind(&DraggableRegionsTestHandler::DestroyTest, this), 500);
|
||||
break;
|
||||
case kStepWithoutRegions: {
|
||||
// Should not be reached.
|
||||
EXPECT_TRUE(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Step {
|
||||
kStepWithRegions,
|
||||
kStepWithChangingRegions1,
|
||||
kStepWithChangingRegions2,
|
||||
kStepWithoutRegions,
|
||||
} step_;
|
||||
|
||||
TrackCallback did_call_on_draggable_regions_changed_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// Verify that draggable regions work.
|
||||
TEST(DraggableRegionsTest, DraggableRegions) {
|
||||
CefRefPtr<DraggableRegionsTestHandler> handler =
|
||||
new DraggableRegionsTestHandler();
|
||||
handler->ExecuteTest();
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
@@ -805,7 +805,7 @@ class OSRTestHandler : public RoutingTestHandler,
|
||||
|
||||
bool StartDragging(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefDragData> drag_data,
|
||||
DragOperationsMask allowed_ops,
|
||||
CefRenderHandler::DragOperationsMask allowed_ops,
|
||||
int x, int y) override {
|
||||
if (test_type_ == OSR_TEST_DRAG_DROP_START_DRAGGING && started()) {
|
||||
DestroySucceededTestSoon();
|
||||
|
@@ -309,3 +309,134 @@ TEST(ParserTest, ParseCSSColor) {
|
||||
EXPECT_FALSE(CefParseCSSColor(value, false, color));
|
||||
EXPECT_EQ(0U, color);
|
||||
}
|
||||
|
||||
|
||||
TEST(ParserTest, ParseJSONInvalid) {
|
||||
const char data[] = "This is my test data";
|
||||
CefRefPtr<CefValue> value = CefParseJSON(data, JSON_PARSER_RFC);
|
||||
EXPECT_FALSE(value.get());
|
||||
}
|
||||
|
||||
TEST(ParserTest, ParseJSONNull) {
|
||||
const char data[] = "{\"key1\":null}";
|
||||
CefRefPtr<CefValue> value = CefParseJSON(data, JSON_PARSER_RFC);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(value->IsValid());
|
||||
EXPECT_TRUE(value->GetType() == VTYPE_DICTIONARY);
|
||||
EXPECT_FALSE(value->IsOwned());
|
||||
CefRefPtr<CefDictionaryValue> dict = value->GetDictionary();
|
||||
CefDictionaryValue::KeyList key_list;
|
||||
EXPECT_TRUE(dict->GetKeys(key_list));
|
||||
EXPECT_EQ((size_t)1, key_list.size());
|
||||
EXPECT_EQ("key1", key_list[0].ToString());
|
||||
EXPECT_EQ(VTYPE_NULL, dict->GetType("key1"));
|
||||
|
||||
// generate string from parsed result
|
||||
CefString result = CefWriteJSON(value, JSON_WRITER_DEFAULT);
|
||||
CefString expected_result = data;
|
||||
EXPECT_EQ(expected_result, result);
|
||||
}
|
||||
|
||||
TEST(ParserTest, WriteJSONBinary) {
|
||||
const char data[] = "\00\01\02";
|
||||
CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
|
||||
CefRefPtr<CefBinaryValue> binary = CefBinaryValue::Create(data, sizeof(data));
|
||||
dict->SetBinary("key1", binary);
|
||||
CefRefPtr<CefValue> node = CefValue::Create();
|
||||
node->SetDictionary(dict);
|
||||
CefString result = CefWriteJSON(node, JSON_WRITER_DEFAULT);
|
||||
CefString expect_result = "";
|
||||
// binary data will be omitted.
|
||||
EXPECT_EQ(expect_result, result);
|
||||
}
|
||||
|
||||
TEST(ParserTest, ParseJSONDictionary) {
|
||||
const char data[] = "{\"key1\":\"value1\",\"key2\":123,\"key3\":[1,2,3]}";
|
||||
CefRefPtr<CefValue> value = CefParseJSON(data, JSON_PARSER_RFC);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(value->IsValid());
|
||||
EXPECT_FALSE(value->IsOwned());
|
||||
EXPECT_TRUE(value->GetType() == VTYPE_DICTIONARY);
|
||||
CefRefPtr<CefDictionaryValue> dict = value->GetDictionary();
|
||||
CefDictionaryValue::KeyList key_list;
|
||||
EXPECT_TRUE(dict->GetKeys(key_list));
|
||||
EXPECT_EQ((size_t)3, key_list.size());
|
||||
EXPECT_EQ("key1", key_list[0].ToString());
|
||||
EXPECT_EQ("key2", key_list[1].ToString());
|
||||
EXPECT_EQ("key3", key_list[2].ToString());
|
||||
EXPECT_EQ(VTYPE_STRING, dict->GetType("key1"));
|
||||
EXPECT_EQ(dict->GetString("key1"), "value1");
|
||||
EXPECT_EQ(VTYPE_INT, dict->GetType("key2"));
|
||||
EXPECT_EQ(123, dict->GetInt("key2"));
|
||||
EXPECT_EQ(VTYPE_LIST, dict->GetType("key3"));
|
||||
CefRefPtr<CefListValue> key3 = dict->GetList("key3");
|
||||
EXPECT_TRUE(NULL != key3);
|
||||
EXPECT_TRUE(key3->IsValid());
|
||||
EXPECT_EQ((size_t)3, key3->GetSize());
|
||||
EXPECT_EQ(1, key3->GetInt(0));
|
||||
EXPECT_EQ(2, key3->GetInt(1));
|
||||
EXPECT_EQ(3, key3->GetInt(2));
|
||||
|
||||
// generate string from parsed result
|
||||
CefString result = CefWriteJSON(value, JSON_WRITER_DEFAULT);
|
||||
CefString expected_result = data;
|
||||
EXPECT_EQ(expected_result, result);
|
||||
}
|
||||
|
||||
TEST(ParserTest, ParseJSONList) {
|
||||
const char data[] = "[\"value1\", 123, {\"key3\": [1, 2, 3]}]";
|
||||
CefRefPtr<CefValue> value = CefParseJSON(data, JSON_PARSER_RFC);
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(value->IsValid());
|
||||
EXPECT_TRUE(value->GetType() == VTYPE_LIST);
|
||||
EXPECT_FALSE(value->IsOwned());
|
||||
CefRefPtr<CefListValue> list = value->GetList();
|
||||
EXPECT_TRUE(NULL != list);
|
||||
EXPECT_TRUE(list->IsValid());
|
||||
EXPECT_EQ((size_t)3, list->GetSize());
|
||||
|
||||
EXPECT_EQ(VTYPE_STRING, list->GetType(0));
|
||||
EXPECT_EQ(list->GetString(0), "value1");
|
||||
EXPECT_EQ(VTYPE_INT, list->GetType(1));
|
||||
EXPECT_EQ(123, list->GetInt(1));
|
||||
EXPECT_EQ(VTYPE_DICTIONARY, list->GetType(2));
|
||||
CefRefPtr<CefDictionaryValue> dict = list->GetDictionary(2);
|
||||
CefDictionaryValue::KeyList key_list2;
|
||||
EXPECT_TRUE(dict->GetKeys(key_list2));
|
||||
EXPECT_EQ((size_t)1, key_list2.size());
|
||||
CefRefPtr<CefListValue> list2 = dict->GetList("key3");
|
||||
EXPECT_EQ((size_t)3, list2->GetSize());
|
||||
EXPECT_EQ(1, list2->GetInt(0));
|
||||
EXPECT_EQ(2, list2->GetInt(1));
|
||||
EXPECT_EQ(3, list2->GetInt(2));
|
||||
|
||||
// generate string from parsed result
|
||||
CefString result = CefWriteJSON(value, JSON_WRITER_DEFAULT);
|
||||
CefString expected_result = "[\"value1\",123,{\"key3\":[1,2,3]}]";
|
||||
EXPECT_EQ(expected_result.ToString(), result.ToString());
|
||||
}
|
||||
|
||||
TEST(ParserTest, ParseJSONAndReturnErrorInvalid) {
|
||||
const char data[] = "This is my test data";
|
||||
cef_json_parser_error_t error_code;
|
||||
CefString error_msg;
|
||||
CefRefPtr<CefValue> value = CefParseJSONAndReturnError(data,
|
||||
JSON_PARSER_RFC, error_code, error_msg);
|
||||
CefString expect_error_msg = "Line: 1, column: 1, Unexpected token.";
|
||||
EXPECT_FALSE(value.get());
|
||||
EXPECT_EQ(JSON_UNEXPECTED_TOKEN, error_code);
|
||||
EXPECT_EQ(expect_error_msg, error_msg);
|
||||
}
|
||||
|
||||
TEST(ParserTest, ParseJSONAndReturnErrorTrailingComma) {
|
||||
const char data[] = "{\"key1\":123,}";
|
||||
cef_json_parser_error_t error_code;
|
||||
CefString error_msg;
|
||||
CefRefPtr<CefValue> value = CefParseJSONAndReturnError(data,
|
||||
JSON_PARSER_RFC, error_code, error_msg);
|
||||
CefString expect_error_msg =
|
||||
"Line: 1, column: 13, Trailing comma not allowed.";
|
||||
EXPECT_FALSE(value.get());
|
||||
EXPECT_EQ(JSON_TRAILING_COMMA, error_code);
|
||||
EXPECT_EQ(expect_error_msg, error_msg);
|
||||
}
|
||||
|
1714
tests/unittests/resource_manager_unittest.cc
Normal file
1714
tests/unittests/resource_manager_unittest.cc
Normal file
File diff suppressed because it is too large
Load Diff
@@ -274,9 +274,10 @@ void TestHandler::DestroyTest() {
|
||||
ui_thread_helper_.reset(NULL);
|
||||
}
|
||||
|
||||
void TestHandler::OnTestTimeout(int timeout_ms) {
|
||||
void TestHandler::OnTestTimeout(int timeout_ms, bool treat_as_error) {
|
||||
EXPECT_UI_THREAD();
|
||||
EXPECT_TRUE(false) << "Test timed out after " << timeout_ms << "ms";
|
||||
if (treat_as_error)
|
||||
EXPECT_TRUE(false) << "Test timed out after " << timeout_ms << "ms";
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
@@ -322,21 +323,24 @@ void TestHandler::ClearResources() {
|
||||
resource_map_.clear();
|
||||
}
|
||||
|
||||
void TestHandler::SetTestTimeout(int timeout_ms) {
|
||||
void TestHandler::SetTestTimeout(int timeout_ms, bool treat_as_error) {
|
||||
if (!CefCurrentlyOn(TID_UI)) {
|
||||
CefPostTask(TID_UI, base::Bind(&TestHandler::SetTestTimeout, this,
|
||||
timeout_ms));
|
||||
timeout_ms, treat_as_error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (CefCommandLine::GetGlobalCommandLine()->HasSwitch("disable-test-timeout"))
|
||||
if (treat_as_error &&
|
||||
CefCommandLine::GetGlobalCommandLine()->HasSwitch(
|
||||
"disable-test-timeout")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use a weak reference to |this| via UIThreadHelper so that the TestHandler
|
||||
// can be destroyed before the timeout expires.
|
||||
GetUIThreadHelper()->PostDelayedTask(
|
||||
base::Bind(&TestHandler::OnTestTimeout, base::Unretained(this),
|
||||
timeout_ms),
|
||||
timeout_ms, treat_as_error),
|
||||
timeout_ms);
|
||||
}
|
||||
|
||||
|
@@ -37,6 +37,7 @@ class TestHandler : public CefClient,
|
||||
public CefDialogHandler,
|
||||
public CefDisplayHandler,
|
||||
public CefDownloadHandler,
|
||||
public CefDragHandler,
|
||||
public CefGeolocationHandler,
|
||||
public CefJSDialogHandler,
|
||||
public CefLifeSpanHandler,
|
||||
@@ -139,6 +140,9 @@ class TestHandler : public CefClient,
|
||||
CefRefPtr<CefDownloadHandler> GetDownloadHandler() override {
|
||||
return this;
|
||||
}
|
||||
CefRefPtr<CefDragHandler> GetDragHandler() override {
|
||||
return this;
|
||||
}
|
||||
CefRefPtr<CefGeolocationHandler> GetGeolocationHandler() override {
|
||||
return this;
|
||||
}
|
||||
@@ -162,6 +166,11 @@ class TestHandler : public CefClient,
|
||||
const CefString& suggested_name,
|
||||
CefRefPtr<CefBeforeDownloadCallback> callback) override {}
|
||||
|
||||
// CefDragHandler methods
|
||||
void OnDraggableRegionsChanged(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
const std::vector<CefDraggableRegion>& regions) override {}
|
||||
|
||||
// CefLifeSpanHandler methods
|
||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;
|
||||
@@ -212,7 +221,7 @@ class TestHandler : public CefClient,
|
||||
|
||||
// Called on the UI thread if the test times out as a result of calling
|
||||
// SetTestTimeout(). Calls DestroyTest() by default.
|
||||
virtual void OnTestTimeout(int timeout_ms);
|
||||
virtual void OnTestTimeout(int timeout_ms, bool treat_as_error);
|
||||
|
||||
// Called from CreateBrowser() to optionally set per-browser settings.
|
||||
virtual void PopulateBrowserSettings(CefBrowserSettings* settings) {}
|
||||
@@ -233,7 +242,7 @@ class TestHandler : public CefClient,
|
||||
}
|
||||
|
||||
// Call OnTestTimeout() after the specified amount of time.
|
||||
void SetTestTimeout(int timeout_ms = 5000);
|
||||
void SetTestTimeout(int timeout_ms = 5000, bool treat_as_error = true);
|
||||
|
||||
// Signal that the test is complete. This will be called automatically when
|
||||
// all existing non-popup browsers are closed if
|
||||
|
@@ -555,7 +555,7 @@ if platform == 'windows':
|
||||
python_exe = 'python.bat'
|
||||
else:
|
||||
git_exe = 'git'
|
||||
python_exe = 'git'
|
||||
python_exe = 'python'
|
||||
|
||||
|
||||
##
|
||||
|
@@ -378,6 +378,7 @@ _simpletypes = {
|
||||
'char': ['char', '0'],
|
||||
'char* const': ['char* const', 'NULL'],
|
||||
'cef_color_t': ['cef_color_t', '0'],
|
||||
'cef_json_parser_error_t': ['cef_json_parser_error_t', 'JSON_NO_ERROR'],
|
||||
'CefCursorHandle' : ['cef_cursor_handle_t', 'kNullCursorHandle'],
|
||||
'CefEventHandle' : ['cef_event_handle_t', 'kNullEventHandle'],
|
||||
'CefWindowHandle' : ['cef_window_handle_t', 'kNullWindowHandle'],
|
||||
@@ -385,6 +386,7 @@ _simpletypes = {
|
||||
'CefPoint' : ['cef_point_t', 'CefPoint()'],
|
||||
'CefRect' : ['cef_rect_t', 'CefRect()'],
|
||||
'CefSize' : ['cef_size_t', 'CefSize()'],
|
||||
'CefDraggableRegion' : ['cef_draggable_region_t', 'CefDraggableRegion()'],
|
||||
'CefPageRange' : ['cef_page_range_t', 'CefPageRange()'],
|
||||
'CefThreadId' : ['cef_thread_id_t', 'TID_UI'],
|
||||
'CefTime' : ['cef_time_t', 'CefTime()'],
|
||||
|
Reference in New Issue
Block a user