InspectorClientQt.cpp [plain text]
#include "config.h"
#include "InspectorClientQt.h"
#include "Frame.h"
#include "FrameView.h"
#include "InspectorController.h"
#include "InspectorFrontend.h"
#include "InspectorServerQt.h"
#include "NotImplemented.h"
#include "Page.h"
#include "PlatformString.h"
#include "ScriptDebugServer.h"
#include "qwebinspector.h"
#include "qwebinspector_p.h"
#include "qwebpage.h"
#include "qwebpage_p.h"
#include "qwebview.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
#include <QtCore/QSettings>
#include <QtCore/QVariant>
namespace WebCore {
static const QLatin1String settingStoragePrefix("Qt/QtWebKit/QWebInspector/");
static const QLatin1String settingStorageTypeSuffix(".type");
class InspectorClientWebPage : public QWebPage {
Q_OBJECT
friend class InspectorClientQt;
public:
InspectorClientWebPage(QObject* parent = 0)
: QWebPage(parent)
{
connect(mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), SLOT(javaScriptWindowObjectCleared()));
}
QWebPage* createWindow(QWebPage::WebWindowType)
{
QWebView* view = new QWebView;
QWebPage* page = new QWebPage;
view->setPage(page);
view->setAttribute(Qt::WA_DeleteOnClose);
return page;
}
public slots:
void javaScriptWindowObjectCleared()
{
#ifndef QT_NO_PROPERTIES
QVariant inspectorJavaScriptWindowObjects = property("_q_inspectorJavaScriptWindowObjects");
if (!inspectorJavaScriptWindowObjects.isValid())
return;
QMap<QString, QVariant> javaScriptNameObjectMap = inspectorJavaScriptWindowObjects.toMap();
QWebFrame* frame = mainFrame();
QMap<QString, QVariant>::const_iterator it = javaScriptNameObjectMap.constBegin();
for ( ; it != javaScriptNameObjectMap.constEnd(); ++it) {
QString name = it.key();
QVariant value = it.value();
QObject* obj = value.value<QObject*>();
frame->addToJavaScriptWindowObject(name, obj);
}
#endif
}
};
namespace {
#if ENABLE(INSPECTOR)
class InspectorFrontendSettingsQt : public InspectorFrontendClientLocal::Settings {
public:
virtual ~InspectorFrontendSettingsQt() { }
virtual String getProperty(const String& name)
{
#ifdef QT_NO_SETTINGS
Q_UNUSED(name)
Q_UNUSED(value)
qWarning("QWebInspector: QSettings is not supported by Qt.");
return String();
#else
QSettings qsettings;
if (qsettings.status() == QSettings::AccessError) {
qWarning("QWebInspector: QSettings couldn't read configuration setting [%s].",
qPrintable(static_cast<QString>(name)));
return String();
}
QString settingKey(settingStoragePrefix + QString(name));
QString storedValueType = qsettings.value(settingKey + settingStorageTypeSuffix).toString();
QVariant storedValue = qsettings.value(settingKey);
storedValue.convert(QVariant::nameToType(storedValueType.toAscii().data()));
return variantToSetting(storedValue);
#endif // QT_NO_SETTINGS
}
virtual void setProperty(const String& name, const String& value)
{
#ifdef QT_NO_SETTINGS
Q_UNUSED(name)
Q_UNUSED(value)
qWarning("QWebInspector: QSettings is not supported by Qt.");
#else
QSettings qsettings;
if (qsettings.status() == QSettings::AccessError) {
qWarning("QWebInspector: QSettings couldn't persist configuration setting [%s].",
qPrintable(static_cast<QString>(name)));
return;
}
QVariant valueToStore = settingToVariant(value);
QString settingKey(settingStoragePrefix + QString(name));
qsettings.setValue(settingKey, valueToStore);
qsettings.setValue(settingKey + settingStorageTypeSuffix, QLatin1String(QVariant::typeToName(valueToStore.type())));
#endif // QT_NO_SETTINGS
}
private:
static String variantToSetting(const QVariant& qvariant)
{
String retVal;
switch (qvariant.type()) {
case QVariant::Bool:
retVal = qvariant.toBool() ? "true" : "false";
break;
case QVariant::String:
retVal = qvariant.toString();
break;
default:
break;
}
return retVal;
}
static QVariant settingToVariant(const String& setting)
{
QVariant retVal;
retVal.setValue(static_cast<QString>(setting));
return retVal;
}
};
#endif // ENABLE(INSPECTOR)
}
InspectorClientQt::InspectorClientQt(QWebPage* page)
: m_inspectedWebPage(page)
, m_frontendWebPage(0)
, m_frontendClient(0)
{
InspectorServerQt* webInspectorServer = InspectorServerQt::server();
if (webInspectorServer)
webInspectorServer->registerClient(this);
}
void InspectorClientQt::inspectorDestroyed()
{
#if ENABLE(INSPECTOR)
if (m_frontendClient)
m_frontendClient->inspectorClientDestroyed();
InspectorServerQt* webInspectorServer = InspectorServerQt::server();
if (webInspectorServer)
webInspectorServer->unregisterClient(this);
delete this;
#endif
}
void InspectorClientQt::openInspectorFrontend(WebCore::InspectorController* inspectorController)
{
#if ENABLE(INSPECTOR)
OwnPtr<QWebView> inspectorView = adoptPtr(new QWebView);
InspectorClientWebPage* inspectorPage = new InspectorClientWebPage(inspectorView.get());
inspectorView->setPage(inspectorPage);
QWebInspector* inspector = m_inspectedWebPage->d->getOrCreateInspector();
if (m_inspectedWebPage->d->inspector->d->remoteFrontend)
return;
QUrl inspectorUrl;
#ifndef QT_NO_PROPERTIES
inspectorUrl = inspector->property("_q_inspectorUrl").toUrl();
#endif
if (!inspectorUrl.isValid())
inspectorUrl = QUrl(QLatin1String("qrc:/webkit/inspector/inspector.html"));
#ifndef QT_NO_PROPERTIES
QVariant inspectorJavaScriptWindowObjects = inspector->property("_q_inspectorJavaScriptWindowObjects");
if (inspectorJavaScriptWindowObjects.isValid())
inspectorPage->setProperty("_q_inspectorJavaScriptWindowObjects", inspectorJavaScriptWindowObjects);
#endif
inspectorView->page()->mainFrame()->load(inspectorUrl);
m_inspectedWebPage->d->inspectorFrontend = inspectorView.get();
inspector->d->setFrontend(inspectorView.get());
InspectorController* controller = inspectorView->page()->d->page->inspectorController();
OwnPtr<InspectorFrontendClientQt> frontendClient = adoptPtr(new InspectorFrontendClientQt(m_inspectedWebPage, inspectorView.release(), this));
m_frontendClient = frontendClient.get();
controller->setInspectorFrontendClient(frontendClient.release());
m_frontendWebPage = inspectorPage;
#endif
}
void InspectorClientQt::releaseFrontendPage()
{
m_frontendWebPage = 0;
m_frontendClient = 0;
}
void InspectorClientQt::attachAndReplaceRemoteFrontend(RemoteFrontendChannel* channel)
{
#if ENABLE(INSPECTOR)
m_inspectedWebPage->d->inspector->d->attachAndReplaceRemoteFrontend(channel);
m_inspectedWebPage->d->inspectorController()->connectFrontend();
#endif
}
void InspectorClientQt::detachRemoteFrontend()
{
#if ENABLE(INSPECTOR)
m_inspectedWebPage->d->inspector->d->detachRemoteFrontend();
m_inspectedWebPage->d->inspectorController()->disconnectFrontend();
#endif
}
void InspectorClientQt::highlight(Node*)
{
hideHighlight();
}
void InspectorClientQt::hideHighlight()
{
WebCore::Frame* frame = m_inspectedWebPage->d->page->mainFrame();
if (frame) {
QRect rect = m_inspectedWebPage->mainFrame()->geometry();
if (!rect.isEmpty())
frame->view()->invalidateRect(rect);
}
}
bool InspectorClientQt::sendMessageToFrontend(const String& message)
{
#if ENABLE(INSPECTOR)
if (m_inspectedWebPage->d->inspector->d->remoteFrontend) {
RemoteFrontendChannel* session = qobject_cast<RemoteFrontendChannel*>(m_inspectedWebPage->d->inspector->d->remoteFrontend);
if (session)
session->sendMessageToFrontend(message);
return true;
}
if (!m_frontendWebPage)
return false;
Page* frontendPage = QWebPagePrivate::core(m_frontendWebPage);
return doDispatchMessageOnFrontendPage(frontendPage, message);
#else
return false;
#endif
}
#if ENABLE(INSPECTOR)
InspectorFrontendClientQt::InspectorFrontendClientQt(QWebPage* inspectedWebPage, PassOwnPtr<QWebView> inspectorView, InspectorClientQt* inspectorClient)
: InspectorFrontendClientLocal(inspectedWebPage->d->page->inspectorController(), inspectorView->page()->d->page, adoptPtr(new InspectorFrontendSettingsQt()))
, m_inspectedWebPage(inspectedWebPage)
, m_inspectorView(inspectorView)
, m_destroyingInspectorView(false)
, m_inspectorClient(inspectorClient)
{
}
InspectorFrontendClientQt::~InspectorFrontendClientQt()
{
ASSERT(m_destroyingInspectorView);
if (m_inspectorClient)
m_inspectorClient->releaseFrontendPage();
}
void InspectorFrontendClientQt::frontendLoaded()
{
InspectorFrontendClientLocal::frontendLoaded();
setAttachedWindow(true);
}
String InspectorFrontendClientQt::localizedStringsURL()
{
notImplemented();
return String();
}
String InspectorFrontendClientQt::hiddenPanels()
{
notImplemented();
return String();
}
void InspectorFrontendClientQt::bringToFront()
{
updateWindowTitle();
}
void InspectorFrontendClientQt::closeWindow()
{
destroyInspectorView(true);
}
void InspectorFrontendClientQt::disconnectFromBackend()
{
destroyInspectorView(false);
}
void InspectorFrontendClientQt::attachWindow()
{
notImplemented();
}
void InspectorFrontendClientQt::detachWindow()
{
notImplemented();
}
void InspectorFrontendClientQt::setAttachedWindowHeight(unsigned)
{
notImplemented();
}
void InspectorFrontendClientQt::inspectedURLChanged(const String& newURL)
{
m_inspectedURL = newURL;
updateWindowTitle();
}
void InspectorFrontendClientQt::updateWindowTitle()
{
if (m_inspectedWebPage->d->inspector) {
QString caption = QCoreApplication::translate("QWebPage", "Web Inspector - %2").arg(m_inspectedURL);
m_inspectedWebPage->d->inspector->setWindowTitle(caption);
}
}
void InspectorFrontendClientQt::destroyInspectorView(bool notifyInspectorController)
{
if (m_destroyingInspectorView)
return;
m_destroyingInspectorView = true;
if (m_inspectedWebPage) {
m_inspectedWebPage->d->getOrCreateInspector()->d->setFrontend(0);
}
#if ENABLE(INSPECTOR)
if (notifyInspectorController)
m_inspectedWebPage->d->inspectorController()->disconnectFrontend();
#endif
if (m_inspectorClient)
m_inspectorClient->releaseFrontendPage();
OwnPtr<QWebView> inspectorView = m_inspectorView.release();
}
void InspectorFrontendClientQt::inspectorClientDestroyed()
{
m_inspectorClient = 0;
m_inspectedWebPage = 0;
}
#endif
}
#include "InspectorClientQt.moc"