diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-02-04 13:50:57 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-02-04 14:13:39 +0100 |
commit | 6722bbbf4ea2ddcdd9194f26a883029ec3afc39a (patch) | |
tree | c3290b82fac21c4990be8472ae6cb4ca043205cf /src | |
parent | 41d69eb0fa2375f0da6ba9b35136f5598be4b3a4 (diff) | |
parent | 82f4d13a13b40d9cb7710f6dd4190175a272a394 (diff) |
Merge branch '5.6' into dev
Change-Id: I0bb971f01ee1e02da768f336680c8ec0254ab2b0
Diffstat (limited to 'src')
34 files changed, 366 insertions, 162 deletions
diff --git a/src/3rdparty b/src/3rdparty -Subproject 1334c7619425f44b0473c1c808ed1005fdb3e2a +Subproject f8c56902fad36d8b43902d81ddc585e543c31b4 diff --git a/src/core/api/qwebenginecookiestore.cpp b/src/core/api/qwebenginecookiestore.cpp index 136fef9d2..06912ce92 100644 --- a/src/core/api/qwebenginecookiestore.cpp +++ b/src/core/api/qwebenginecookiestore.cpp @@ -194,38 +194,6 @@ void QWebEngineCookieStorePrivate::onCookieChanged(const QNetworkCookie &cookie, */ /*! - \class QWebEngineCookieStore::FilterRequest - \inmodule QtWebEngineCore - \since 5.6 - \brief The FilterRequest class specifies the properties of a cookie. - - The class specifies the properties of a cookie and determines whether the cookie should be - accepted. The class is used as an argument to a filter installed via setCookieFilter(). -*/ - -/*! - \variable QWebEngineCookieStore::FilterRequest::accepted - \brief Whether the cookie shall be accepted. - - The default is \c true. -*/ - -/*! - \variable QWebEngineCookieStore::FilterRequest::firstPartyUrl - \brief The URL of the page that triggered the setting of the cookie. -*/ - -/*! - \variable QWebEngineCookieStore::FilterRequest::cookieLine - \brief The content of the cookie. -*/ - -/*! - \variable QWebEngineCookieStore::FilterRequest::cookieSource - \brief The URL of the site that sets the cookie. -*/ - -/*! \fn void QWebEngineCookieStore::cookieAdded(const QNetworkCookie &cookie) This signal is emitted whenever a new \a cookie is added to the cookie store. diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp index c286cb709..7325b131e 100644 --- a/src/core/api/qwebengineurlrequestinfo.cpp +++ b/src/core/api/qwebengineurlrequestinfo.cpp @@ -104,13 +104,11 @@ ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, Q */ /*! - \fn bool QWebEngineUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) + \fn void QWebEngineUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) Reimplementing this virtual function and setting the interceptor on a profile makes it possible to intercept URL requests. This function is executed on the IO thread, and therefore running long tasks here will block networking. - If this function is only used for inspection, it should return \c false, in which - case any modification to \a info will be ignored. \sa QWebEngineProfile::setRequestInterceptor */ diff --git a/src/core/api/qwebengineurlrequestjob.h b/src/core/api/qwebengineurlrequestjob.h index 8801e6bc0..afa542d7e 100644 --- a/src/core/api/qwebengineurlrequestjob.h +++ b/src/core/api/qwebengineurlrequestjob.h @@ -47,8 +47,8 @@ #include <QtCore/qurl.h> namespace QtWebEngineCore { -class URLRequestCustomJob; class URLRequestCustomJobDelegate; +class URLRequestCustomJobShared; } // namespace QT_BEGIN_NAMESPACE @@ -79,7 +79,7 @@ public: private: QWebEngineUrlRequestJob(QtWebEngineCore::URLRequestCustomJobDelegate *); - friend class QtWebEngineCore::URLRequestCustomJob; + friend class QtWebEngineCore::URLRequestCustomJobShared; QtWebEngineCore::URLRequestCustomJobDelegate* d_ptr; }; diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp index 94770f0bb..dea845e68 100644 --- a/src/core/browser_context_adapter.cpp +++ b/src/core/browser_context_adapter.cpp @@ -357,7 +357,7 @@ QHash<QByteArray, QWebEngineUrlSchemeHandler *> &BrowserContextAdapter::customUr void BrowserContextAdapter::updateCustomUrlSchemeHandlers() { if (m_browserContext->url_request_getter_.get()) - m_browserContext->url_request_getter_->updateStorageSettings(); + m_browserContext->url_request_getter_->updateJobFactory(); } bool BrowserContextAdapter::removeCustomUrlSchemeHandler(QWebEngineUrlSchemeHandler *handler) diff --git a/src/core/config/common.pri b/src/core/config/common.pri new file mode 100644 index 000000000..c5921a573 --- /dev/null +++ b/src/core/config/common.pri @@ -0,0 +1,10 @@ +# Shared configuration for all our supported platforms + +# Trigger Qt-specific build conditions. +GYP_CONFIG += use_qt=1 +# We do not want to ship more external binary blobs, so let v8 embed its startup data. +GYP_CONFIG += v8_use_external_startup_data=0 +# Disable printing since we don't support it yet +GYP_CONFIG += enable_basic_printing=0 enable_print_preview=0 +# WebSpeech requires Google API keys and adds dependencies on speex and flac. +GYP_CONFIG += enable_web_speech=0 diff --git a/src/core/config/embedded_qnx.pri b/src/core/config/embedded_qnx.pri index 7fd35c976..34470d2d8 100644 --- a/src/core/config/embedded_qnx.pri +++ b/src/core/config/embedded_qnx.pri @@ -1,5 +1,7 @@ GYP_ARGS += "-D qt_os=\"embedded_qnx\" -I config/embedded_qnx.gypi" +include(common.pri) + GYP_CONFIG += \ disable_nacl=1 \ enable_plugins=0 \ diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri index f2883bc32..2fa6aa5c6 100644 --- a/src/core/config/linux.pri +++ b/src/core/config/linux.pri @@ -1,3 +1,5 @@ +include(common.pri) + # linux_use_bundled_gold currently relies on a hardcoded relative path from chromium/src/out/(Release|Debug) # Disable it along with the -Wl,--threads flag just in case gold isn't installed on the system. GYP_CONFIG += \ @@ -37,7 +39,6 @@ use?(system_libevent): GYP_CONFIG += use_system_libevent=1 use?(system_libwebp): GYP_CONFIG += use_system_libwebp=1 use?(system_libsrtp): GYP_CONFIG += use_system_libsrtp=1 use?(system_libxslt): GYP_CONFIG += use_system_libxml=1 -use?(system_flac): GYP_CONFIG += use_system_flac=1 use?(system_jsoncpp): GYP_CONFIG += use_system_jsoncpp=1 use?(system_opus): GYP_CONFIG += use_system_opus=1 use?(system_snappy): GYP_CONFIG += use_system_snappy=1 diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri index f11dba1b7..dd2affca9 100644 --- a/src/core/config/mac_osx.pri +++ b/src/core/config/mac_osx.pri @@ -1,3 +1,5 @@ +include(common.pri) + QMAKE_CLANG_DIR = "/usr" QMAKE_CLANG_PATH = $$eval(QMAKE_MAC_SDK.macx-clang.$${QMAKE_MAC_SDK}.QMAKE_CXX) !isEmpty(QMAKE_CLANG_PATH) { diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri index 153a4fe72..ab4037d1f 100644 --- a/src/core/config/windows.pri +++ b/src/core/config/windows.pri @@ -1,5 +1,7 @@ GYP_ARGS += "-D qt_os=\"win32\" -I config/windows.gypi" +include(common.pri) + GYP_CONFIG += \ disable_nacl=1 \ remoting=0 \ diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp index 83b9b7a41..d14e13137 100644 --- a/src/core/content_client_qt.cpp +++ b/src/core/content_client_qt.cpp @@ -150,13 +150,14 @@ void AddPepperFlashFromSystem(std::vector<content::PepperPluginInfo>* plugins) pluginPaths << ppapiPluginsPath() + QStringLiteral("/PepperFlashPlayer.plugin"); #endif #if defined(Q_OS_LINUX) - pluginPaths << "/usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so" // Ubuntu + pluginPaths << "/opt/google/chrome/PepperFlash/libpepflashplayer.so" // Google Chrome + << "/usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so" // Ubuntu << "/usr/lib/PepperFlash/libpepflashplayer.so" // Arch << "/usr/lib64/chromium/PepperFlash/libpepflashplayer.so"; // OpenSuSE pluginPaths << ppapiPluginsPath() + QStringLiteral("/libpepflashplayer.so"); #endif for (auto it = pluginPaths.constBegin(); it != pluginPaths.constEnd(); ++it) { - if (!QFile(*it).exists()) + if (!QFile::exists(*it)) continue; plugins->push_back(CreatePepperFlashInfo(QtWebEngineCore::toFilePath(*it), std::string())); } @@ -165,7 +166,7 @@ void AddPepperFlashFromSystem(std::vector<content::PepperPluginInfo>* plugins) void AddPepperFlashFromCommandLine(std::vector<content::PepperPluginInfo>* plugins) { const base::CommandLine::StringType flash_path = base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(switches::kPpapiFlashPath); - if (flash_path.empty() || !QFile(QtWebEngineCore::toQt(flash_path)).exists()) + if (flash_path.empty() || !QFile::exists(QtWebEngineCore::toQt(flash_path))) return; // Read pepper flash plugin version from command-line. (e.g. 16.0.0.235) diff --git a/src/core/core_module.pro b/src/core/core_module.pro index ef6921dd5..f30af83fc 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -78,13 +78,22 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat } !contains(QT_CONFIG, qt_framework): contains(QT_CONFIG, private_tests) { - ICU_TARGET = $$shell_path($$[QT_INSTALL_DATA/get]/resources/icudtl.dat) - ICU_FILE = $$shell_path($$OUT_PWD/$$getConfigDir()/icudtl.dat) - icu_rule.target = $$ICU_TARGET - unix: icu_rule.commands = if [ -e $$ICU_FILE ] ; then $$QMAKE_COPY $$ICU_FILE $$ICU_TARGET ; fi - win32: icu_rule.commands = if exist $$ICU_FILE ( $$QMAKE_COPY $$ICU_FILE $$ICU_TARGET ) - - QMAKE_EXTRA_TARGETS += icu_rule - PRE_TARGETDEPS += $$ICU_TARGET + # + # Copy essential files to the qtbase build directory (for non-installed developer builds) + # + + icudt2build.input = icu.files + icudt2build.output = $$[QT_INSTALL_DATA/get]/resources/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT} + icudt2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} + icudt2build.name = COPY ${QMAKE_FILE_IN} + icudt2build.CONFIG = no_link no_clean target_predeps + + resources2build.input = resources.files + resources2build.output = $$[QT_INSTALL_DATA/get]/resources/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT} + resources2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} + resources2build.name = COPY ${QMAKE_FILE_IN} + resources2build.CONFIG = no_link no_clean target_predeps + + QMAKE_EXTRA_COMPILERS += icudt2build resources2build } } diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 3a5a8aa6b..308a99fd3 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -826,7 +826,9 @@ void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEve if (!m_gestureProvider.OnTouchEvent(motionEvent).succeeded) return; - blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent, false); + bool causesScrollingIfUncancelled = true; + blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent, + causesScrollingIfUncancelled); m_host->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent)); } diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index afb3c231e..bcbc5f4ef 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -131,8 +131,9 @@ void URLRequestContextGetterQt::updateStorageSettings() content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE) )); - if (m_storage) + if (m_storage) { content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateStorage, this)); + } } } @@ -287,7 +288,7 @@ void URLRequestContextGetterQt::generateUserAgent() Q_ASSERT(m_urlRequestContext); Q_ASSERT(m_storage); - m_storage->set_http_user_agent_settings(scoped_ptr<net::HttpUserAgentSettings>(new HttpUserAgentSettingsQt(m_browserContext))); + m_storage->set_http_user_agent_settings(scoped_ptr<net::HttpUserAgentSettings>(new HttpUserAgentSettingsQt(m_browserContext.constData()))); } void URLRequestContextGetterQt::updateHttpCache() @@ -298,6 +299,13 @@ void URLRequestContextGetterQt::updateHttpCache() } } +void URLRequestContextGetterQt::updateJobFactory() +{ + Q_ASSERT(m_jobFactory); + + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateJobFactory, this)); +} + static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &first, const net::HttpNetworkSession::Params &second) { if (first.transport_security_state != second.transport_security_state) @@ -413,8 +421,8 @@ void URLRequestContextGetterQt::clearCurrentCacheBackend() void URLRequestContextGetterQt::generateJobFactory() { Q_ASSERT(m_urlRequestContext); - Q_ASSERT(!m_jobFactory); + m_jobFactory.reset(); scoped_ptr<net::URLRequestJobFactoryImpl> jobFactory(new net::URLRequestJobFactoryImpl()); { @@ -422,7 +430,6 @@ void URLRequestContextGetterQt::generateJobFactory() content::ProtocolHandlerMap::iterator it = m_protocolHandlers.find(url::kBlobScheme); Q_ASSERT(it != m_protocolHandlers.end()); jobFactory->SetProtocolHandler(it->first, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(it->second.release())); - m_protocolHandlers.clear(); } jobFactory->SetProtocolHandler(url::kDataScheme, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new net::DataProtocolHandler())); diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h index 4adbefef7..8d911e4d4 100644 --- a/src/core/url_request_context_getter_qt.h +++ b/src/core/url_request_context_getter_qt.h @@ -81,6 +81,7 @@ public: void updateCookieStore(); void updateHttpCache(); void clearHttpCache(); + void updateJobFactory(); private: virtual ~URLRequestContextGetterQt(); @@ -98,7 +99,7 @@ private: bool m_ignoreCertificateErrors; QAtomicInt m_updateCookieStore; QAtomicInt m_updateHttpCache; - BrowserContextAdapter *m_browserContext; + QExplicitlySharedDataPointer<BrowserContextAdapter> m_browserContext; content::ProtocolHandlerMap m_protocolHandlers; QAtomicPointer<net::ProxyConfigService> m_proxyConfigService; diff --git a/src/core/url_request_custom_job.cpp b/src/core/url_request_custom_job.cpp index 5bb29bcc3..f8a47b2b1 100644 --- a/src/core/url_request_custom_job.cpp +++ b/src/core/url_request_custom_job.cpp @@ -59,46 +59,33 @@ namespace QtWebEngineCore { URLRequestCustomJob::URLRequestCustomJob(URLRequest *request, NetworkDelegate *networkDelegate, QWebEngineUrlSchemeHandler *schemeHandler) : URLRequestJob(request, networkDelegate) - , m_device(0) , m_schemeHandler(schemeHandler) - , m_error(0) - , m_started(false) - , m_weakFactoryIO(this) - , m_weakFactoryUI(this) + , m_shared(new URLRequestCustomJobShared(this)) { } URLRequestCustomJob::~URLRequestCustomJob() { - QMutexLocker lock(&m_mutex); - if (m_delegate) { - m_delegate->m_job = 0; - m_delegate->deleteLater(); - } - if (m_device && m_device->isOpen()) - m_device->close(); + if (m_shared) + m_shared->killJob(); +} + +static void startAsync(URLRequestCustomJobShared *shared) +{ + shared->startAsync(); } void URLRequestCustomJob::Start() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(&URLRequestCustomJob::startAsync, m_weakFactoryIO.GetWeakPtr())); + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(&startAsync, m_shared)); } void URLRequestCustomJob::Kill() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - if (m_delegate) { - m_delegate->m_job = 0; - m_delegate->deleteLater(); - } - m_delegate = 0; - if (m_device && m_device->isOpen()) - m_device->close(); - m_device = 0; - m_weakFactoryIO.InvalidateWeakPtrs(); - m_weakFactoryUI.InvalidateWeakPtrs(); + if (m_shared) + m_shared->killJob(); + m_shared = 0; URLRequestJob::Kill(); } @@ -106,8 +93,11 @@ void URLRequestCustomJob::Kill() bool URLRequestCustomJob::GetMimeType(std::string *mimeType) const { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (m_mimeType.size() > 0) { - *mimeType = m_mimeType; + if (!m_shared) + return false; + QMutexLocker lock(&m_shared->m_mutex); + if (m_shared->m_mimeType.size() > 0) { + *mimeType = m_shared->m_mimeType; return true; } return false; @@ -116,8 +106,11 @@ bool URLRequestCustomJob::GetMimeType(std::string *mimeType) const bool URLRequestCustomJob::GetCharset(std::string* charset) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (m_charset.size() > 0) { - *charset = m_charset; + if (!m_shared) + return false; + QMutexLocker lock(&m_shared->m_mutex); + if (m_shared->m_charset.size() > 0) { + *charset = m_shared->m_charset; return true; } return false; @@ -126,124 +119,223 @@ bool URLRequestCustomJob::GetCharset(std::string* charset) bool URLRequestCustomJob::IsRedirectResponse(GURL* location, int* http_status_code) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - if (m_redirect.is_valid()) { - *location = m_redirect; + if (!m_shared) + return false; + QMutexLocker lock(&m_shared->m_mutex); + if (m_shared->m_redirect.is_valid()) { + *location = m_shared->m_redirect; *http_status_code = 303; return true; } return false; } -void URLRequestCustomJob::setReplyMimeType(const std::string &mimeType) +bool URLRequestCustomJob::ReadRawData(IOBuffer *buf, int bufSize, int *bytesRead) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + Q_ASSERT(bytesRead); + Q_ASSERT(m_shared); + QMutexLocker lock(&m_shared->m_mutex); + qint64 rv = m_shared->m_device ? m_shared->m_device->read(buf->data(), bufSize) : -1; + if (rv >= 0) { + *bytesRead = static_cast<int>(rv); + return true; + } else { + NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, ERR_FAILED)); + } + return false; +} + +URLRequestCustomJobShared::URLRequestCustomJobShared(URLRequestCustomJob *job) + : m_mutex(QMutex::Recursive) + , m_job(job) + , m_delegate(0) + , m_error(0) + , m_started(false) + , m_asyncInitialized(false) + , m_weakFactory(this) +{ +} + +URLRequestCustomJobShared::~URLRequestCustomJobShared() +{ + Q_ASSERT(!m_job); + Q_ASSERT(!m_delegate); +} + +void URLRequestCustomJobShared::killJob() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + QMutexLocker lock(&m_mutex); + m_job = 0; + bool doDelete = false; + if (m_delegate) { + m_delegate->deleteLater(); + } else { + // Do not delete yet if startAsync has not yet run. + doDelete = m_asyncInitialized; + } + if (m_device && m_device->isOpen()) + m_device->close(); + m_device = 0; + m_weakFactory.InvalidateWeakPtrs(); + lock.unlock(); + if (doDelete) + delete this; +} + +void URLRequestCustomJobShared::unsetJobDelegate() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + QMutexLocker lock(&m_mutex); + m_delegate = 0; + bool doDelete = false; + if (m_job) + abort(); + else + doDelete = true; + lock.unlock(); + if (doDelete) + delete this; +} + +void URLRequestCustomJobShared::setReplyMimeType(const std::string &mimeType) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + QMutexLocker lock(&m_mutex); m_mimeType = mimeType; } -void URLRequestCustomJob::setReplyCharset(const std::string &charset) +void URLRequestCustomJobShared::setReplyCharset(const std::string &charset) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + QMutexLocker lock(&m_mutex); m_charset = charset; } -void URLRequestCustomJob::setReplyDevice(QIODevice *device) +void URLRequestCustomJobShared::setReplyDevice(QIODevice *device) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); QMutexLocker lock(&m_mutex); + if (!m_job) + return; m_device = device; if (m_device && !m_device->isReadable()) m_device->open(QIODevice::ReadOnly); if (m_device && m_device->isReadable()) - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyStarted, m_weakFactoryUI.GetWeakPtr())); + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyStarted, m_weakFactory.GetWeakPtr())); else fail(ERR_INVALID_URL); } -bool URLRequestCustomJob::ReadRawData(IOBuffer *buf, int bufSize, int *bytesRead) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - Q_ASSERT(bytesRead); - QMutexLocker lock(&m_mutex); - qint64 rv = m_device ? m_device->read(buf->data(), bufSize) : -1; - if (rv >= 0) { - *bytesRead = static_cast<int>(rv); - return true; - } else { - NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, ERR_FAILED)); - } - return false; -} - -void URLRequestCustomJob::redirect(const GURL &url) +void URLRequestCustomJobShared::redirect(const GURL &url) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (m_device || m_error) - return; QMutexLocker lock(&m_mutex); + if (m_device || m_error) + return; + if (!m_job) + return; m_redirect = url; - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyStarted, m_weakFactoryUI.GetWeakPtr())); + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyStarted, m_weakFactory.GetWeakPtr())); } -void URLRequestCustomJob::abort() +void URLRequestCustomJobShared::abort() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); QMutexLocker lock(&m_mutex); if (m_device && m_device->isOpen()) m_device->close(); m_device = 0; - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyCanceled, m_weakFactoryUI.GetWeakPtr())); + if (!m_job) + return; + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyCanceled, m_weakFactory.GetWeakPtr())); } -void URLRequestCustomJob::notifyCanceled() +void URLRequestCustomJobShared::notifyCanceled() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + QMutexLocker lock(&m_mutex); + if (!m_job) + return; if (m_started) - NotifyDone(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED)); + m_job->NotifyDone(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED)); else - NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED)); + m_job->NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED)); } -void URLRequestCustomJob::notifyStarted() +void URLRequestCustomJobShared::notifyStarted() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + QMutexLocker lock(&m_mutex); + if (!m_job) + return; Q_ASSERT(!m_started); m_started = true; - NotifyHeadersComplete(); + m_job->NotifyHeadersComplete(); } -void URLRequestCustomJob::fail(int error) +void URLRequestCustomJobShared::fail(int error) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); QMutexLocker lock(&m_mutex); m_error = error; - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJob::notifyFailure, m_weakFactoryUI.GetWeakPtr())); + if (!m_job) + return; + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyFailure, m_weakFactory.GetWeakPtr())); } -void URLRequestCustomJob::notifyFailure() +void URLRequestCustomJobShared::notifyFailure() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); QMutexLocker lock(&m_mutex); + if (!m_job) + return; if (m_device) m_device->close(); - if (m_started) - NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, m_error)); + const URLRequestStatus status(URLRequestStatus::FAILED, m_error); + const bool started = m_started; + + if (started) + m_job->NotifyDone(status); else - NotifyStartError(URLRequestStatus(URLRequestStatus::FAILED, m_error)); + m_job->NotifyStartError(status); } -void URLRequestCustomJob::startAsync() +GURL URLRequestCustomJobShared::requestUrl() +{ + QMutexLocker lock(&m_mutex); + if (!m_job) + return GURL(); + return m_job->request()->url(); +} + +std::string URLRequestCustomJobShared::requestMethod() +{ + QMutexLocker lock(&m_mutex); + if (!m_job) + return std::string(); + return m_job->request()->method(); +} + +void URLRequestCustomJobShared::startAsync() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); Q_ASSERT(!m_started); Q_ASSERT(!m_delegate); QMutexLocker lock(&m_mutex); + if (!m_job) { + lock.unlock(); + delete this; + return; + } m_delegate = new URLRequestCustomJobDelegate(this); - lock.unlock(); + m_asyncInitialized = true; QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate); - m_schemeHandler->requestStarted(requestJob); + if (m_job) + m_job->m_schemeHandler->requestStarted(requestJob); } } // namespace diff --git a/src/core/url_request_custom_job.h b/src/core/url_request_custom_job.h index e6063f485..98e2478c4 100644 --- a/src/core/url_request_custom_job.h +++ b/src/core/url_request_custom_job.h @@ -53,6 +53,7 @@ QT_FORWARD_DECLARE_CLASS(QWebEngineUrlSchemeHandler) namespace QtWebEngineCore { class URLRequestCustomJobDelegate; +class URLRequestCustomJobShared; // A request job that handles reading custom URL schemes class URLRequestCustomJob : public net::URLRequestJob { @@ -65,6 +66,25 @@ public: virtual bool GetCharset(std::string *charset) Q_DECL_OVERRIDE; virtual bool IsRedirectResponse(GURL* location, int* http_status_code) Q_DECL_OVERRIDE; +protected: + virtual ~URLRequestCustomJob(); + +private: + QWebEngineUrlSchemeHandler *m_schemeHandler; + URLRequestCustomJobShared *m_shared; + + friend class URLRequestCustomJobShared; + + DISALLOW_COPY_AND_ASSIGN(URLRequestCustomJob); +}; + +// A shared state between URLRequestCustomJob living on the IO thread +// and URLRequestCustomJobDelegate living on the UI thread. +class URLRequestCustomJobShared { +public: + URLRequestCustomJobShared(URLRequestCustomJob *job); + ~URLRequestCustomJobShared(); + void setReplyMimeType(const std::string &); void setReplyCharset(const std::string &); void setReplyDevice(QIODevice *); @@ -73,29 +93,28 @@ public: void fail(int); void abort(); -protected: - virtual ~URLRequestCustomJob(); + void killJob(); + void unsetJobDelegate(); + void startAsync(); void notifyStarted(); void notifyFailure(); void notifyCanceled(); -private: + GURL requestUrl(); + std::string requestMethod(); + QMutex m_mutex; QPointer<QIODevice> m_device; - QPointer<URLRequestCustomJobDelegate> m_delegate; - QWebEngineUrlSchemeHandler *m_schemeHandler; + URLRequestCustomJob *m_job; + URLRequestCustomJobDelegate *m_delegate; std::string m_mimeType; std::string m_charset; int m_error; GURL m_redirect; bool m_started; - base::WeakPtrFactory<URLRequestCustomJob> m_weakFactoryIO; - base::WeakPtrFactory<URLRequestCustomJob> m_weakFactoryUI; - - friend class URLRequestCustomJobDelegate; - - DISALLOW_COPY_AND_ASSIGN(URLRequestCustomJob); + bool m_asyncInitialized; + base::WeakPtrFactory<URLRequestCustomJobShared> m_weakFactory; }; } // namespace QtWebEngineCore diff --git a/src/core/url_request_custom_job_delegate.cpp b/src/core/url_request_custom_job_delegate.cpp index f0026bef3..7e806a4e0 100644 --- a/src/core/url_request_custom_job_delegate.cpp +++ b/src/core/url_request_custom_job_delegate.cpp @@ -47,39 +47,40 @@ namespace QtWebEngineCore { -URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJob *job) - : m_job(job) +URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobShared *shared) + : m_shared(shared) { } URLRequestCustomJobDelegate::~URLRequestCustomJobDelegate() { + m_shared->unsetJobDelegate(); } QUrl URLRequestCustomJobDelegate::url() const { - return toQt(m_job->request()->url()); + return toQt(m_shared->requestUrl()); } QByteArray URLRequestCustomJobDelegate::method() const { - return QByteArray::fromStdString(m_job->request()->method()); + return QByteArray::fromStdString(m_shared->requestMethod()); } void URLRequestCustomJobDelegate::setReply(const QByteArray &contentType, QIODevice *device) { - m_job->setReplyMimeType(contentType.toStdString()); - m_job->setReplyDevice(device); + m_shared->setReplyMimeType(contentType.toStdString()); + m_shared->setReplyDevice(device); } void URLRequestCustomJobDelegate::abort() { - m_job->abort(); + m_shared->abort(); } void URLRequestCustomJobDelegate::redirect(const QUrl &url) { - m_job->redirect(toGurl(url)); + m_shared->redirect(toGurl(url)); } void URLRequestCustomJobDelegate::fail(Error error) @@ -105,7 +106,7 @@ void URLRequestCustomJobDelegate::fail(Error error) break; } if (net_error) - m_job->fail(net_error); + m_shared->fail(net_error); } } // namespace diff --git a/src/core/url_request_custom_job_delegate.h b/src/core/url_request_custom_job_delegate.h index 3a3931660..7752d979e 100644 --- a/src/core/url_request_custom_job_delegate.h +++ b/src/core/url_request_custom_job_delegate.h @@ -49,7 +49,7 @@ QT_FORWARD_DECLARE_CLASS(QIODevice) namespace QtWebEngineCore { -class URLRequestCustomJob; +class URLRequestCustomJobShared; class QWEBENGINE_EXPORT URLRequestCustomJobDelegate : public QObject { Q_OBJECT @@ -75,10 +75,10 @@ public: void fail(Error); private: - URLRequestCustomJobDelegate(URLRequestCustomJob *job); + URLRequestCustomJobDelegate(URLRequestCustomJobShared *shared); - friend class URLRequestCustomJob; - URLRequestCustomJob *m_job; + friend class URLRequestCustomJobShared; + URLRequestCustomJobShared *m_shared; }; } // namespace diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 5e6335584..a5c7a756b 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -254,7 +254,7 @@ public: virtual void moveValidationMessage(const QRect &anchor) = 0; RenderProcessTerminationStatus renderProcessExitStatus(int); virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) = 0; - + virtual void requestGeometryChange(const QRect &geometry) = 0; virtual void allowCertificateError(const QSharedPointer<CertificateErrorController> &errorController) = 0; virtual void updateScrollPosition(const QPointF &position) = 0; virtual void updateContentsSize(const QSizeF &size) = 0; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index a3d2d816e..43ecbdf7f 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -336,6 +336,17 @@ void WebContentsDelegateQt::RequestMediaAccessPermission(content::WebContents *w MediaCaptureDevicesDispatcher::GetInstance()->processMediaAccessRequest(m_viewClient, web_contents, request, callback); } +void WebContentsDelegateQt::MoveContents(content::WebContents *source, const gfx::Rect &pos) +{ + Q_UNUSED(source) + m_viewClient->requestGeometryChange(toQt(pos)); +} + +bool WebContentsDelegateQt::IsPopupOrPanel(const content::WebContents *source) const +{ + return source->HasOpener(); +} + void WebContentsDelegateQt::UpdateTargetURL(content::WebContents* source, const GURL& url) { Q_UNUSED(source) diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index afa4030d0..cc00f1f44 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -96,6 +96,8 @@ public: virtual bool AddMessageToConsole(content::WebContents* source, int32 level, const base::string16& message, int32 line_no, const base::string16& source_id) Q_DECL_OVERRIDE; virtual void FindReply(content::WebContents *source, int request_id, int number_of_matches, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) Q_DECL_OVERRIDE; virtual void RequestMediaAccessPermission(content::WebContents* web_contents, const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback) Q_DECL_OVERRIDE; + virtual void MoveContents(content::WebContents *source, const gfx::Rect &pos) Q_DECL_OVERRIDE; + virtual bool IsPopupOrPanel(const content::WebContents *source) const Q_DECL_OVERRIDE; virtual void UpdateTargetURL(content::WebContents* source, const GURL& url) Q_DECL_OVERRIDE; virtual void RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target) Q_DECL_OVERRIDE; virtual void ShowValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view, const base::string16 &main_text, const base::string16 &sub_text) Q_DECL_OVERRIDE; diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp index ee8174af7..a67bce94c 100644 --- a/src/core/web_engine_library_info.cpp +++ b/src/core/web_engine_library_info.cpp @@ -140,7 +140,7 @@ QString subProcessPath() } Q_FOREACH (const QString &candidate, candidatePaths) { - if (QFileInfo(candidate).exists()) { + if (QFileInfo::exists(candidate)) { processPath = candidate; break; } @@ -167,7 +167,7 @@ QString pluginsPath() const QStringList directories = QCoreApplication::libraryPaths(); Q_FOREACH (const QString &dir, directories) { const QString candidate = dir % "/" % QLatin1String("qtwebengine"); - if (QFileInfo(candidate).exists()) { + if (QFileInfo::exists(candidate)) { pluginsPath = candidate; break; } diff --git a/src/webengine/api/qquickwebenginehistory.cpp b/src/webengine/api/qquickwebenginehistory.cpp index ad943dfe8..96a4415e0 100644 --- a/src/webengine/api/qquickwebenginehistory.cpp +++ b/src/webengine/api/qquickwebenginehistory.cpp @@ -261,7 +261,7 @@ QQuickWebEngineHistoryPrivate::~QQuickWebEngineHistoryPrivate() The data models can also be used to create a menu, as illustrated by the following code snippet: - \quotefromfile webengine/quicknanobrowser/browserwindow.qml + \quotefromfile webengine/quicknanobrowser/BrowserWindow.qml \skipto ToolBar \printuntil onObjectRemoved \printuntil } diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 060dd4e49..e4313a4bd 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -176,6 +176,7 @@ public: virtual void moveValidationMessage(const QRect &anchor) Q_DECL_OVERRIDE; virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) Q_DECL_OVERRIDE; + virtual void requestGeometryChange(const QRect &geometry) Q_DECL_OVERRIDE { Q_UNUSED(geometry); } virtual void updateScrollPosition(const QPointF &position) Q_DECL_OVERRIDE; virtual void updateContentsSize(const QSizeF &size) Q_DECL_OVERRIDE; void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions, diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc index 55f6c5504..29b8db42e 100644 --- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc +++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc @@ -47,7 +47,7 @@ \list \li Windows: Visual Studio 2013 or Visual Studio 2015 \li Linux: Clang or GCC version 4.7 or later - \li OS X: Xcode version 5.1 or later + \li OS X: Xcode version 5.1 or later on OS X 10.9 or later \endlist \section1 Pepper Plugin API Support diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc index 39441228d..a242acffc 100644 --- a/src/webengine/doc/src/webengineview.qdoc +++ b/src/webengine/doc/src/webengineview.qdoc @@ -29,6 +29,22 @@ \inqmlmodule QtWebEngine \since QtWebEngine 1.0 \brief A WebEngineView renders web content within a QML application. + + The WebEngineView type enables QML applications to render regions of dynamic web content. It + may share the screen with other QML types, such as a TabView, or fill the screen, as specified + within the QML application. + + \section1 Rendering to OpenGL Surface + + When using a QQuickRenderControl to render a Qt Quick user interface to an OpenGL surface, the + WebEngineView type is not rendered correctly. The web engine view attempts to use a global + OpenGL context created by \l QtWebEngine::initialize(), but there is no public API for accessing + that context in order to share it with the \c QQuickRenderControl context. + + To have the web engine view rendered correctly, it is possible to manually create a new + offscreen context that is shared with the \c QQuickRenderControl and to call the non-public + function \c qt_gl_set_global_share_context(), rather than calling \c initialize(). + If \c initialize() is called after setting a global context, it will do nothing. */ /*! @@ -251,6 +267,9 @@ The script will run in the same \e world as other scripts that are part of the loaded site. + \warning Do not execute lengthy routines in the callback function, because it might block the + rendering of the web content. + See WebEngineView::userScripts for an alternative API to inject scripts. */ diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 62c1adee6..2b448664f 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -112,6 +112,8 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile) , m_isBeingAdopted(false) , m_backgroundColor(Qt::white) , fullscreenMode(false) + , webChannel(nullptr) + , webChannelWorldId(QWebEngineScript::MainWorld) { memset(actions, 0, sizeof(actions)); } @@ -238,6 +240,8 @@ void QWebEnginePagePrivate::adoptNewWindow(WebContentsAdapter *newWebContents, W Q_UNUSED(userGesture); QWebEnginePage *newPage = q->createWindow(toWindowType(disposition)); + if (!newPage) + return; // Mark the new page as being in the process of being adopted, so that a second mouse move event // sent by newWebContents->initialize() gets filtered in RenderWidgetHostViewQt::forwardEvent. @@ -251,7 +255,7 @@ void QWebEnginePagePrivate::adoptNewWindow(WebContentsAdapter *newWebContents, W newPage->d_func()->m_isBeingAdopted = true; // Overwrite the new page's WebContents with ours. - if (newPage && newPage->d_func() != this) { + if (newPage->d_func() != this) { newPage->d_func()->adapter = newWebContents; newWebContents->initialize(newPage->d_func()); if (!initialGeometry.isEmpty()) @@ -430,8 +434,14 @@ void QWebEnginePagePrivate::recreateFromSerializedHistory(QDataStream &input) { QExplicitlySharedDataPointer<WebContentsAdapter> newWebContents = WebContentsAdapter::createFromSerializedNavigationHistory(input, this); if (newWebContents) { + // Keep the old adapter referenced so the user-scripts are not + // unregistered immediately. + QExplicitlySharedDataPointer<WebContentsAdapter> oldWebContents = adapter; adapter = newWebContents.data(); adapter->initialize(this); + if (webChannel) + adapter->setWebChannel(webChannel, webChannelWorldId); + scriptCollection.d->rebindToContents(adapter.data()); } } @@ -593,7 +603,7 @@ QWebEngineSettings *QWebEnginePage::settings() const QWebChannel *QWebEnginePage::webChannel() const { Q_D(const QWebEnginePage); - return d->adapter->webChannel(); + return d->webChannel; } /*! @@ -631,7 +641,11 @@ void QWebEnginePage::setWebChannel(QWebChannel *channel) void QWebEnginePage::setWebChannel(QWebChannel *channel, uint worldId) { Q_D(QWebEnginePage); - d->adapter->setWebChannel(channel, worldId); + if (d->webChannel != channel || d->webChannelWorldId != worldId) { + d->webChannel = channel; + d->webChannelWorldId = worldId; + d->adapter->setWebChannel(channel, worldId); + } } /*! @@ -1197,6 +1211,12 @@ void QWebEnginePagePrivate::renderProcessTerminated(RenderProcessTerminationStat terminationStatus), exitCode); } +void QWebEnginePagePrivate::requestGeometryChange(const QRect &geometry) +{ + Q_Q(QWebEnginePage); + Q_EMIT q->geometryChangeRequested(geometry); +} + void QWebEnginePagePrivate::startDragging(const content::DropData &dropData, Qt::DropActions allowedActions, const QPixmap &pixmap, const QPoint &offset) diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index 2e55bd7c2..ce769169e 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -128,6 +128,7 @@ public: virtual void moveValidationMessage(const QRect &anchor) Q_DECL_OVERRIDE; virtual void renderProcessTerminated(RenderProcessTerminationStatus terminationStatus, int exitCode) Q_DECL_OVERRIDE; + virtual void requestGeometryChange(const QRect &geometry) Q_DECL_OVERRIDE; virtual void updateScrollPosition(const QPointF &position) Q_DECL_OVERRIDE; virtual void updateContentsSize(const QSizeF &size) Q_DECL_OVERRIDE; void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions, @@ -160,6 +161,8 @@ public: bool m_isBeingAdopted; QColor m_backgroundColor; bool fullscreenMode; + QWebChannel *webChannel; + unsigned int webChannelWorldId; mutable QtWebEngineCore::CallbackDirectory m_callbacks; mutable QAction *actions[QWebEnginePage::WebActionCount]; diff --git a/src/webenginewidgets/api/qwebenginescriptcollection.cpp b/src/webenginewidgets/api/qwebenginescriptcollection.cpp index c17d05ce4..c53172261 100644 --- a/src/webenginewidgets/api/qwebenginescriptcollection.cpp +++ b/src/webenginewidgets/api/qwebenginescriptcollection.cpp @@ -223,3 +223,15 @@ void QWebEngineScriptCollectionPrivate::reserve(int capacity) { m_scriptController->reserve(m_contents, capacity); } + +void QWebEngineScriptCollectionPrivate::rebindToContents(QtWebEngineCore::WebContentsAdapter *page) +{ + Q_ASSERT(m_contents); + Q_ASSERT(page); + Q_ASSERT(m_contents != page); + + Q_FOREACH (const UserScript &script, m_scriptController->registeredScripts(m_contents)) { + m_scriptController->addUserScript(script, page); + } + m_contents = page; +} diff --git a/src/webenginewidgets/api/qwebenginescriptcollection_p.h b/src/webenginewidgets/api/qwebenginescriptcollection_p.h index ebb0d1f00..185b590c4 100644 --- a/src/webenginewidgets/api/qwebenginescriptcollection_p.h +++ b/src/webenginewidgets/api/qwebenginescriptcollection_p.h @@ -72,6 +72,8 @@ public: QList<QWebEngineScript> toList(const QString &scriptName = QString()) const; QWebEngineScript find(const QString & name) const; + void rebindToContents(QtWebEngineCore::WebContentsAdapter *contents); + void insert(const QWebEngineScript &); bool remove(const QWebEngineScript &); void clear(); diff --git a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc index 7b87ff7d9..99723c105 100644 --- a/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc +++ b/src/webenginewidgets/doc/src/qtwebkitportingguide.qdoc @@ -279,5 +279,12 @@ \li In the latest HTML standard, any document element can be made editable through the \c contentEditable attribute. So \c runJavaScript is all that is needed: \c{page->runJavascript("document.documentElement.contentEditable = true")} + \row + \li QWebPage::setLinkDelegationPolicy + \li There is no way to connect a signal to run C++ code when a link is clicked. However, + link clicks can be delegated to the Qt application instead of having the HTML handler + engine process them by overloading the QWebEnginePage::acceptNavigationRequest() + function. This is necessary when an HTML document is used as part of the user interface, + and not to display external data, for example, when displaying a list of results. \endtable */ diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc index 3b25bac76..a65d6011f 100644 --- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc @@ -283,8 +283,17 @@ the specified navigation type \a type. \a isMainFrame indicates whether the request corresponds to the main frame or a sub frame. If the function returns \c true, the navigation request is accepted and \c url is loaded. The default implementation accepts all navigation requests. -*/ + This function is called for absolute URLs that are prefixed with \c {http://} or \c {https://} + and for unrecognized schemes, such as \c {mailto:}, which will be handled by QDesktopServices + if accepted. To have this function called also upon receiving navigation requests to local URLs, + prefix the URLs with \c {http://}. + + Navigation requests can be delegated to the Qt application instead of having the HTML handler + engine process them by overloading this function. This is necessary when an HTML document is + used as part of the user interface, and not to display external data, for example, when + displaying a list of results. +*/ /*! \fn void QWebEnginePage::javaScriptAlert(const QUrl &securityOrigin, const QString& msg) @@ -634,6 +643,9 @@ page.runJavaScript("document.title", [](const QVariant &v) { qDebug() << v.toString(); }); \endcode + \warning Do not execute lengthy routines in the callback function, because it might block the + rendering of the web engine page. + See scripts() for an alternative API to inject scripts. */ diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc index 9d03527e1..397b9f51b 100644 --- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc @@ -75,9 +75,9 @@ If you want to provide support for web sites that allow the user to open new windows, such as pop-up windows, you can subclass QWebEngineView and reimplement the createWindow() function. + + \sa {WebEngine Demo Browser Example}, {WebEngine Content Manipulation Example}, {Markdown Editor Example} */ -// FIXME: reintroduce the following when we have proper names for the examples. -// \sa {WebEngine Tab Browser Example}, {WebEngine Fancy Browser Example} /*! |