File indexing completed on 2023-05-30 09:09:51
0001 /* This file is part of the KDE project 0002 * 0003 * Copyright (C) 2000-2003 Simon Hausmann <hausmann@kde.org> 0004 * 2001-2003 George Staikos <staikos@kde.org> 0005 * 2001-2003 Laurent Montel <montel@kde.org> 0006 * 2001-2003 Dirk Mueller <mueller@kde.org> 0007 * 2001-2003 Waldo Bastian <bastian@kde.org> 0008 * 2001-2003 David Faure <faure@kde.org> 0009 * 2001-2003 Daniel Naber <dnaber@kde.org> 0010 * 0011 * This library is free software; you can redistribute it and/or 0012 * modify it under the terms of the GNU Library General Public 0013 * License as published by the Free Software Foundation; either 0014 * version 2 of the License, or (at your option) any later version. 0015 * 0016 * This library is distributed in the hope that it will be useful, 0017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0019 * Library General Public License for more details. 0020 * 0021 * You should have received a copy of the GNU Library General Public License 0022 * along with this library; see the file COPYING.LIB. If not, write to 0023 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0024 * Boston, MA 02110-1301, USA. 0025 */ 0026 0027 #include "khtml_ext.h" 0028 #include "khtmlview.h" 0029 #include "khtml_pagecache.h" 0030 #include "rendering/render_form.h" 0031 #include "rendering/render_image.h" 0032 #include "html/html_imageimpl.h" 0033 #include "misc/loader.h" 0034 #include "dom/html_form.h" 0035 #include "dom/html_image.h" 0036 #include "dom/dom_string.h" 0037 #include "dom/html_document.h" 0038 #include "dom/dom_element.h" 0039 #include "xml/dom_elementimpl.h" 0040 #include <QClipboard> 0041 #include <QFileInfo> 0042 #include <QFileDialog> 0043 #include <QMenu> 0044 #include <QUrl> 0045 #include <QMetaEnum> 0046 #include <QMimeData> 0047 #include <qstandardpaths.h> 0048 #include <qinputdialog.h> 0049 #include <assert.h> 0050 0051 #include <kconfiggroup.h> 0052 #include <ksharedconfig.h> 0053 #include "khtml_debug.h" 0054 #include <klocalizedstring.h> 0055 #include <kjobuidelegate.h> 0056 #include <kio/job.h> 0057 #include <kshell.h> 0058 #include <qsavefile.h> 0059 #include <kstringhandler.h> 0060 #include <ktoolinvocation.h> 0061 #include <kmessagebox.h> 0062 #include <krun.h> 0063 #include <kurifilter.h> 0064 #include <kdesktopfile.h> 0065 #include <qtemporaryfile.h> 0066 #include "khtml_global.h" 0067 #include <kstandardaction.h> 0068 #include <kactioncollection.h> 0069 #include <kactionmenu.h> 0070 0071 #include "khtmlpart_p.h" 0072 0073 KHTMLPartBrowserExtension::KHTMLPartBrowserExtension(KHTMLPart *parent) 0074 : KParts::BrowserExtension(parent) 0075 { 0076 m_part = parent; 0077 setURLDropHandlingEnabled(true); 0078 0079 enableAction("cut", false); 0080 enableAction("copy", false); 0081 enableAction("paste", false); 0082 0083 m_connectedToClipboard = false; 0084 } 0085 0086 int KHTMLPartBrowserExtension::xOffset() 0087 { 0088 return m_part->view()->contentsX(); 0089 } 0090 0091 int KHTMLPartBrowserExtension::yOffset() 0092 { 0093 return m_part->view()->contentsY(); 0094 } 0095 0096 void KHTMLPartBrowserExtension::saveState(QDataStream &stream) 0097 { 0098 //qCDebug(KHTML_LOG) << "saveState!"; 0099 m_part->saveState(stream); 0100 } 0101 0102 void KHTMLPartBrowserExtension::restoreState(QDataStream &stream) 0103 { 0104 //qCDebug(KHTML_LOG) << "restoreState!"; 0105 m_part->restoreState(stream); 0106 } 0107 0108 void KHTMLPartBrowserExtension::editableWidgetFocused(QWidget *widget) 0109 { 0110 m_editableFormWidget = widget; 0111 updateEditActions(); 0112 0113 if (!m_connectedToClipboard && m_editableFormWidget) { 0114 connect(QApplication::clipboard(), SIGNAL(dataChanged()), 0115 this, SLOT(updateEditActions())); 0116 0117 if (m_editableFormWidget->inherits("QLineEdit") || m_editableFormWidget->inherits("QTextEdit")) 0118 connect(m_editableFormWidget, SIGNAL(selectionChanged()), 0119 this, SLOT(updateEditActions())); 0120 0121 m_connectedToClipboard = true; 0122 } 0123 editableWidgetFocused(); 0124 } 0125 0126 void KHTMLPartBrowserExtension::editableWidgetBlurred(QWidget * /*widget*/) 0127 { 0128 QWidget *oldWidget = m_editableFormWidget; 0129 0130 m_editableFormWidget = nullptr; 0131 enableAction("cut", false); 0132 enableAction("paste", false); 0133 m_part->emitSelectionChanged(); 0134 0135 if (m_connectedToClipboard) { 0136 disconnect(QApplication::clipboard(), SIGNAL(dataChanged()), 0137 this, SLOT(updateEditActions())); 0138 0139 if (oldWidget) { 0140 if (oldWidget->inherits("QLineEdit") || oldWidget->inherits("QTextEdit")) 0141 disconnect(oldWidget, SIGNAL(selectionChanged()), 0142 this, SLOT(updateEditActions())); 0143 } 0144 0145 m_connectedToClipboard = false; 0146 } 0147 editableWidgetBlurred(); 0148 } 0149 0150 void KHTMLPartBrowserExtension::setExtensionProxy(KParts::BrowserExtension *proxy) 0151 { 0152 if (m_extensionProxy) { 0153 disconnect(m_extensionProxy, SIGNAL(enableAction(const char*,bool)), 0154 this, SLOT(extensionProxyActionEnabled(const char*,bool))); 0155 if (m_extensionProxy->inherits("KHTMLPartBrowserExtension")) { 0156 disconnect(m_extensionProxy, SIGNAL(editableWidgetFocused()), 0157 this, SLOT(extensionProxyEditableWidgetFocused())); 0158 disconnect(m_extensionProxy, SIGNAL(editableWidgetBlurred()), 0159 this, SLOT(extensionProxyEditableWidgetBlurred())); 0160 } 0161 } 0162 0163 m_extensionProxy = proxy; 0164 0165 if (m_extensionProxy) { 0166 connect(m_extensionProxy, SIGNAL(enableAction(const char*,bool)), 0167 this, SLOT(extensionProxyActionEnabled(const char*,bool))); 0168 if (m_extensionProxy->inherits("KHTMLPartBrowserExtension")) { 0169 connect(m_extensionProxy, SIGNAL(editableWidgetFocused()), 0170 this, SLOT(extensionProxyEditableWidgetFocused())); 0171 connect(m_extensionProxy, SIGNAL(editableWidgetBlurred()), 0172 this, SLOT(extensionProxyEditableWidgetBlurred())); 0173 } 0174 0175 enableAction("cut", m_extensionProxy->isActionEnabled("cut")); 0176 enableAction("copy", m_extensionProxy->isActionEnabled("copy")); 0177 enableAction("paste", m_extensionProxy->isActionEnabled("paste")); 0178 } else { 0179 updateEditActions(); 0180 enableAction("copy", false); // ### re-check this 0181 } 0182 } 0183 0184 void KHTMLPartBrowserExtension::cut() 0185 { 0186 if (m_extensionProxy) { 0187 callExtensionProxyMethod("cut"); 0188 return; 0189 } 0190 0191 if (!m_editableFormWidget) { 0192 return; 0193 } 0194 0195 QLineEdit *lineEdit = qobject_cast<QLineEdit *>(m_editableFormWidget); 0196 if (lineEdit && !lineEdit->isReadOnly()) { 0197 lineEdit->cut(); 0198 } 0199 QTextEdit *textEdit = qobject_cast<QTextEdit *>(m_editableFormWidget); 0200 if (textEdit && !textEdit->isReadOnly()) { 0201 textEdit->cut(); 0202 } 0203 } 0204 0205 void KHTMLPartBrowserExtension::copy() 0206 { 0207 if (m_extensionProxy) { 0208 callExtensionProxyMethod("copy"); 0209 return; 0210 } 0211 0212 if (!m_editableFormWidget) { 0213 // get selected text and paste to the clipboard 0214 QString text = m_part->selectedText(); 0215 text.replace(QChar(0xa0), ' '); 0216 //qCDebug(KHTML_LOG) << text; 0217 0218 QClipboard *cb = QApplication::clipboard(); 0219 disconnect(cb, SIGNAL(selectionChanged()), m_part, SLOT(slotClearSelection())); 0220 #ifndef QT_NO_MIMECLIPBOARD 0221 QString htmltext; 0222 /* 0223 * When selectionModeEnabled, that means the user has just selected 0224 * the text, not ctrl+c to copy it. The selection clipboard 0225 * doesn't seem to support mime type, so to save time, don't calculate 0226 * the selected text as html. 0227 * optomisation disabled for now until everything else works. 0228 */ 0229 //if(!cb->selectionModeEnabled()) 0230 htmltext = m_part->selectedTextAsHTML(); 0231 QMimeData *mimeData = new QMimeData; 0232 mimeData->setText(text); 0233 if (!htmltext.isEmpty()) { 0234 htmltext.replace(QChar(0xa0), ' '); 0235 mimeData->setHtml(htmltext); 0236 } 0237 cb->setMimeData(mimeData); 0238 #else 0239 cb->setText(text); 0240 #endif 0241 0242 connect(cb, SIGNAL(selectionChanged()), m_part, SLOT(slotClearSelection())); 0243 } else { 0244 QLineEdit *lineEdit = qobject_cast<QLineEdit *>(m_editableFormWidget); 0245 if (lineEdit) { 0246 lineEdit->copy(); 0247 } 0248 QTextEdit *textEdit = qobject_cast<QTextEdit *>(m_editableFormWidget); 0249 if (textEdit) { 0250 textEdit->copy(); 0251 } 0252 } 0253 } 0254 0255 void KHTMLPartBrowserExtension::searchProvider() 0256 { 0257 QAction *action = qobject_cast<QAction *>(sender()); 0258 if (action) { 0259 QUrl url = action->data().toUrl(); 0260 if (url.host().isEmpty()) { 0261 KUriFilterData data(action->data().toString()); 0262 if (KUriFilter::self()->filterSearchUri(data, KUriFilter::WebShortcutFilter)) { 0263 url = data.uri(); 0264 } 0265 } 0266 0267 KParts::BrowserArguments browserArgs; 0268 browserArgs.frameName = "_blank"; 0269 emit m_part->browserExtension()->openUrlRequest(url, KParts::OpenUrlArguments(), browserArgs); 0270 } 0271 } 0272 0273 void KHTMLPartBrowserExtension::paste() 0274 { 0275 if (m_extensionProxy) { 0276 callExtensionProxyMethod("paste"); 0277 return; 0278 } 0279 0280 if (!m_editableFormWidget) { 0281 return; 0282 } 0283 0284 QLineEdit *lineEdit = qobject_cast<QLineEdit *>(m_editableFormWidget); 0285 if (lineEdit && !lineEdit->isReadOnly()) { 0286 lineEdit->paste(); 0287 } 0288 QTextEdit *textEdit = qobject_cast<QTextEdit *>(m_editableFormWidget); 0289 if (textEdit && !textEdit->isReadOnly()) { 0290 textEdit->paste(); 0291 } 0292 } 0293 0294 void KHTMLPartBrowserExtension::callExtensionProxyMethod(const char *method) 0295 { 0296 if (!m_extensionProxy) { 0297 return; 0298 } 0299 0300 QMetaObject::invokeMethod(m_extensionProxy, method, Qt::DirectConnection); 0301 } 0302 0303 void KHTMLPartBrowserExtension::updateEditActions() 0304 { 0305 if (!m_editableFormWidget) { 0306 enableAction("cut", false); 0307 enableAction("copy", false); 0308 enableAction("paste", false); 0309 return; 0310 } 0311 0312 // ### duplicated from KonqMainWindow::slotClipboardDataChanged 0313 #ifndef QT_NO_MIMECLIPBOARD // Handle minimalized versions of Qt Embedded 0314 const QMimeData *data = QApplication::clipboard()->mimeData(); 0315 enableAction("paste", data->hasText()); 0316 #else 0317 QString data = QApplication::clipboard()->text(); 0318 enableAction("paste", data.contains("://")); 0319 #endif 0320 bool hasSelection = false; 0321 0322 if (m_editableFormWidget) { 0323 if (qobject_cast<QLineEdit *>(m_editableFormWidget)) { 0324 hasSelection = static_cast<QLineEdit *>(&(*m_editableFormWidget))->hasSelectedText(); 0325 } else if (qobject_cast<QTextEdit *>(m_editableFormWidget)) { 0326 hasSelection = static_cast<QTextEdit *>(&(*m_editableFormWidget))->textCursor().hasSelection(); 0327 } 0328 } 0329 0330 enableAction("copy", hasSelection); 0331 enableAction("cut", hasSelection); 0332 } 0333 0334 void KHTMLPartBrowserExtension::extensionProxyEditableWidgetFocused() 0335 { 0336 editableWidgetFocused(); 0337 } 0338 0339 void KHTMLPartBrowserExtension::extensionProxyEditableWidgetBlurred() 0340 { 0341 editableWidgetBlurred(); 0342 } 0343 0344 void KHTMLPartBrowserExtension::extensionProxyActionEnabled(const char *action, bool enable) 0345 { 0346 // only forward enableAction calls for actions we actually do forward 0347 if (strcmp(action, "cut") == 0 || 0348 strcmp(action, "copy") == 0 || 0349 strcmp(action, "paste") == 0) { 0350 enableAction(action, enable); 0351 } 0352 } 0353 0354 void KHTMLPartBrowserExtension::reparseConfiguration() 0355 { 0356 m_part->reparseConfiguration(); 0357 } 0358 0359 void KHTMLPartBrowserExtension::print() 0360 { 0361 m_part->view()->print(); 0362 } 0363 0364 void KHTMLPartBrowserExtension::disableScrolling() 0365 { 0366 QScrollArea *scrollArea = m_part->view(); 0367 if (scrollArea) { 0368 scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 0369 scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 0370 } 0371 } 0372 0373 class KHTMLPopupGUIClient::KHTMLPopupGUIClientPrivate 0374 { 0375 public: 0376 KHTMLPart *m_khtml; 0377 QUrl m_url; 0378 QUrl m_imageURL; 0379 QPixmap m_pixmap; 0380 QString m_suggestedFilename; 0381 KActionCollection *m_actionCollection; 0382 KParts::BrowserExtension::ActionGroupMap actionGroups; 0383 }; 0384 0385 KHTMLPopupGUIClient::KHTMLPopupGUIClient(KHTMLPart *khtml, const QUrl &url) 0386 : QObject(khtml), d(new KHTMLPopupGUIClientPrivate) 0387 { 0388 d->m_khtml = khtml; 0389 d->m_url = url; 0390 d->m_actionCollection = new KActionCollection(this); 0391 bool isImage = false; 0392 bool hasSelection = khtml->hasSelection(); 0393 0394 DOM::Element e = khtml->nodeUnderMouse(); 0395 0396 if (!e.isNull() && (e.elementId() == ID_IMG || 0397 (e.elementId() == ID_INPUT && !static_cast<DOM::HTMLInputElement>(e).src().isEmpty()))) { 0398 if (e.elementId() == ID_IMG) { 0399 DOM::HTMLImageElementImpl *ie = static_cast<DOM::HTMLImageElementImpl *>(e.handle()); 0400 khtml::RenderImage *ri = dynamic_cast<khtml::RenderImage *>(ie->renderer()); 0401 if (ri && ri->contentObject()) { 0402 d->m_suggestedFilename = static_cast<khtml::CachedImage *>(ri->contentObject())->suggestedFilename(); 0403 } 0404 } 0405 isImage = true; 0406 } 0407 0408 if (hasSelection) { 0409 QList<QAction *> editActions; 0410 QAction *copyAction = d->m_actionCollection->addAction(KStandardAction::Copy, "copy", 0411 d->m_khtml->browserExtension(), SLOT(copy())); 0412 0413 copyAction->setText(i18n("&Copy Text")); 0414 copyAction->setEnabled(d->m_khtml->browserExtension()->isActionEnabled("copy")); 0415 editActions.append(copyAction); 0416 0417 editActions.append(khtml->actionCollection()->action("selectAll")); 0418 0419 addSearchActions(editActions); 0420 0421 QString selectedTextURL = selectedTextAsOneLine(d->m_khtml); 0422 if (selectedTextURL.contains("://") && QUrl(selectedTextURL).isValid()) { 0423 if (selectedTextURL.length() > 18) { 0424 selectedTextURL.truncate(15); 0425 selectedTextURL += "..."; 0426 } 0427 QAction *action = new QAction(i18n("Open '%1'", selectedTextURL), this); 0428 d->m_actionCollection->addAction("openSelection", action); 0429 action->setIcon(QIcon::fromTheme("window-new")); 0430 connect(action, SIGNAL(triggered(bool)), this, SLOT(openSelection())); 0431 editActions.append(action); 0432 } 0433 0434 QAction *separator = new QAction(d->m_actionCollection); 0435 separator->setSeparator(true); 0436 editActions.append(separator); 0437 0438 d->actionGroups.insert("editactions", editActions); 0439 } 0440 0441 if (!url.isEmpty()) { 0442 QList<QAction *> linkActions; 0443 if (url.scheme() == "mailto") { 0444 QAction *action = new QAction(i18n("&Copy Email Address"), this); 0445 d->m_actionCollection->addAction("copylinklocation", action); 0446 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotCopyLinkLocation())); 0447 linkActions.append(action); 0448 } else { 0449 QAction *action = new QAction(i18n("&Save Link As..."), this); 0450 d->m_actionCollection->addAction("savelinkas", action); 0451 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotSaveLinkAs())); 0452 linkActions.append(action); 0453 0454 action = new QAction(i18n("&Copy Link Address"), this); 0455 d->m_actionCollection->addAction("copylinklocation", action); 0456 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotCopyLinkLocation())); 0457 linkActions.append(action); 0458 } 0459 d->actionGroups.insert("linkactions", linkActions); 0460 } 0461 0462 QList<QAction *> partActions; 0463 // frameset? -> add "Reload Frame" etc. 0464 if (!hasSelection) { 0465 if (khtml->parentPart()) { 0466 KActionMenu *menu = new KActionMenu(i18nc("@title:menu HTML frame/iframe", "Frame"), this); 0467 QAction *action = new QAction(i18n("Open in New &Window"), this); 0468 d->m_actionCollection->addAction("frameinwindow", action); 0469 action->setIcon(QIcon::fromTheme("window-new")); 0470 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotFrameInWindow())); 0471 menu->addAction(action); 0472 0473 action = new QAction(i18n("Open in &This Window"), this); 0474 d->m_actionCollection->addAction("frameintop", action); 0475 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotFrameInTop())); 0476 menu->addAction(action); 0477 0478 action = new QAction(i18n("Open in &New Tab"), this); 0479 d->m_actionCollection->addAction("frameintab", action); 0480 action->setIcon(QIcon::fromTheme("tab-new")); 0481 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotFrameInTab())); 0482 menu->addAction(action); 0483 0484 action = new QAction(d->m_actionCollection); 0485 action->setSeparator(true); 0486 menu->addAction(action); 0487 0488 action = new QAction(i18n("Reload Frame"), this); 0489 d->m_actionCollection->addAction("reloadframe", action); 0490 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotReloadFrame())); 0491 menu->addAction(action); 0492 0493 action = new QAction(i18n("Print Frame..."), this); 0494 d->m_actionCollection->addAction("printFrame", action); 0495 action->setIcon(QIcon::fromTheme("document-print-frame")); 0496 connect(action, SIGNAL(triggered(bool)), d->m_khtml->browserExtension(), SLOT(print())); 0497 menu->addAction(action); 0498 0499 action = new QAction(i18n("Save &Frame As..."), this); 0500 d->m_actionCollection->addAction("saveFrame", action); 0501 connect(action, SIGNAL(triggered(bool)), d->m_khtml, SLOT(slotSaveFrame())); 0502 menu->addAction(action); 0503 0504 action = new QAction(i18n("View Frame Source"), this); 0505 d->m_actionCollection->addAction("viewFrameSource", action); 0506 connect(action, SIGNAL(triggered(bool)), d->m_khtml, SLOT(slotViewDocumentSource())); 0507 menu->addAction(action); 0508 0509 action = new QAction(i18n("View Frame Information"), this); 0510 d->m_actionCollection->addAction("viewFrameInfo", action); 0511 connect(action, SIGNAL(triggered(bool)), d->m_khtml, SLOT(slotViewPageInfo())); 0512 0513 action = new QAction(d->m_actionCollection); 0514 action->setSeparator(true); 0515 menu->addAction(action); 0516 0517 if (KHTMLGlobal::defaultHTMLSettings()->isAdFilterEnabled()) { 0518 if (khtml->d->m_frame->m_type == khtml::ChildFrame::IFrame) { 0519 action = new QAction(i18n("Block IFrame..."), this); 0520 d->m_actionCollection->addAction("blockiframe", action); 0521 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotBlockIFrame())); 0522 menu->addAction(action); 0523 } 0524 } 0525 0526 partActions.append(menu); 0527 } 0528 } 0529 0530 if (isImage) { 0531 if (e.elementId() == ID_IMG) { 0532 d->m_imageURL = QUrl(static_cast<DOM::HTMLImageElement>(e).src().string()); 0533 DOM::HTMLImageElementImpl *imageimpl = static_cast<DOM::HTMLImageElementImpl *>(e.handle()); 0534 Q_ASSERT(imageimpl); 0535 if (imageimpl) { // should be true always. right? 0536 if (imageimpl->complete()) { 0537 d->m_pixmap = imageimpl->currentPixmap(); 0538 } 0539 } 0540 } else { 0541 d->m_imageURL = QUrl(static_cast<DOM::HTMLInputElement>(e).src().string()); 0542 } 0543 QAction *action = new QAction(i18n("Save Image As..."), this); 0544 d->m_actionCollection->addAction("saveimageas", action); 0545 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotSaveImageAs())); 0546 partActions.append(action); 0547 0548 action = new QAction(i18n("Send Image..."), this); 0549 d->m_actionCollection->addAction("sendimage", action); 0550 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotSendImage())); 0551 partActions.append(action); 0552 0553 #ifndef QT_NO_MIMECLIPBOARD 0554 action = new QAction(i18n("Copy Image"), this); 0555 d->m_actionCollection->addAction("copyimage", action); 0556 action->setEnabled(!d->m_pixmap.isNull()); 0557 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotCopyImage())); 0558 partActions.append(action); 0559 #endif 0560 0561 if (d->m_pixmap.isNull()) { //fallback to image location if still loading the image. this will always be true if ifdef QT_NO_MIMECLIPBOARD 0562 action = new QAction(i18n("Copy Image Location"), this); 0563 d->m_actionCollection->addAction("copyimagelocation", action); 0564 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotCopyImageLocation())); 0565 partActions.append(action); 0566 } 0567 0568 QString actionText = d->m_suggestedFilename.isEmpty() ? 0569 KStringHandler::csqueeze(d->m_imageURL.fileName() + d->m_imageURL.query(), 25) 0570 : d->m_suggestedFilename; 0571 action = new QAction(i18n("View Image (%1)", actionText.replace("&", "&&")), this); 0572 d->m_actionCollection->addAction("viewimage", action); 0573 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotViewImage())); 0574 partActions.append(action); 0575 0576 if (KHTMLGlobal::defaultHTMLSettings()->isAdFilterEnabled()) { 0577 action = new QAction(i18n("Block Image..."), this); 0578 d->m_actionCollection->addAction("blockimage", action); 0579 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotBlockImage())); 0580 partActions.append(action); 0581 0582 if (!d->m_imageURL.host().isEmpty() && 0583 !d->m_imageURL.scheme().isEmpty()) { 0584 action = new QAction(i18n("Block Images From %1", d->m_imageURL.host()), this); 0585 d->m_actionCollection->addAction("blockhost", action); 0586 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotBlockHost())); 0587 partActions.append(action); 0588 } 0589 } 0590 QAction *separator = new QAction(d->m_actionCollection); 0591 separator->setSeparator(true); 0592 partActions.append(separator); 0593 } 0594 0595 if (isImage || url.isEmpty()) { 0596 QAction *action = new QAction(i18n("Stop Animations"), this); 0597 d->m_actionCollection->addAction("stopanimations", action); 0598 connect(action, SIGNAL(triggered(bool)), this, SLOT(slotStopAnimations())); 0599 partActions.append(action); 0600 QAction *separator = new QAction(d->m_actionCollection); 0601 separator->setSeparator(true); 0602 partActions.append(separator); 0603 } 0604 if (!hasSelection && url.isEmpty()) { // only when right-clicking on the page itself 0605 partActions.append(khtml->actionCollection()->action("viewDocumentSource")); 0606 } 0607 if (!hasSelection && url.isEmpty() && !isImage) { 0608 partActions.append(khtml->actionCollection()->action("setEncoding")); 0609 } 0610 d->actionGroups.insert("partactions", partActions); 0611 } 0612 0613 KHTMLPopupGUIClient::~KHTMLPopupGUIClient() 0614 { 0615 delete d->m_actionCollection; 0616 delete d; 0617 } 0618 0619 void KHTMLPopupGUIClient::addSearchActions(QList<QAction *> &editActions) 0620 { 0621 QString selectedText = d->m_khtml->simplifiedSelectedText(); 0622 // replace linefeeds with spaces 0623 selectedText = selectedText.replace(QChar(10), QChar(32)).trimmed(); 0624 0625 if (selectedText.isEmpty()) { 0626 return; 0627 } 0628 0629 KUriFilterData data(selectedText); 0630 QStringList alternateProviders; 0631 alternateProviders << "google" << "google_groups" << "google_news" << "webster" << "dmoz" << "wikipedia"; 0632 data.setAlternateSearchProviders(alternateProviders); 0633 data.setAlternateDefaultSearchProvider("google"); 0634 0635 if (KUriFilter::self()->filterSearchUri(data, KUriFilter::NormalTextFilter)) { 0636 const QString squeezedText = KStringHandler::rsqueeze(selectedText, 21); 0637 QAction *action = new QAction(i18n("Search for '%1' with %2", 0638 squeezedText, data.searchProvider()), this); 0639 action->setData(QUrl(data.uri())); 0640 action->setIcon(QIcon::fromTheme(data.iconName())); 0641 connect(action, SIGNAL(triggered(bool)), d->m_khtml->browserExtension(), SLOT(searchProvider())); 0642 d->m_actionCollection->addAction("defaultSearchProvider", action); 0643 editActions.append(action); 0644 0645 const QStringList preferredSearchProviders = data.preferredSearchProviders(); 0646 if (!preferredSearchProviders.isEmpty()) { 0647 KActionMenu *providerList = new KActionMenu(i18n("Search for '%1' with", squeezedText), this); 0648 Q_FOREACH (const QString &searchProvider, preferredSearchProviders) { 0649 if (searchProvider == data.searchProvider()) { 0650 continue; 0651 } 0652 QAction *action = new QAction(searchProvider, this); 0653 action->setData(data.queryForPreferredSearchProvider(searchProvider)); 0654 d->m_actionCollection->addAction(searchProvider, action); 0655 action->setIcon(QIcon::fromTheme(data.iconNameForPreferredSearchProvider(searchProvider))); 0656 connect(action, SIGNAL(triggered(bool)), d->m_khtml->browserExtension(), SLOT(searchProvider())); 0657 providerList->addAction(action); 0658 } 0659 d->m_actionCollection->addAction("searchProviderList", providerList); 0660 editActions.append(providerList); 0661 } 0662 } 0663 } 0664 0665 QString KHTMLPopupGUIClient::selectedTextAsOneLine(KHTMLPart *part) 0666 { 0667 QString text = part->simplifiedSelectedText(); 0668 // in addition to what simplifiedSelectedText does, 0669 // remove linefeeds and any whitespace surrounding it (#113177), 0670 // to get it all in a single line. 0671 text.remove(QRegExp("[\\s]*\\n+[\\s]*")); 0672 return text; 0673 } 0674 0675 void KHTMLPopupGUIClient::openSelection() 0676 { 0677 KParts::BrowserArguments browserArgs; 0678 browserArgs.frameName = "_blank"; 0679 0680 QUrl url(selectedTextAsOneLine(d->m_khtml)); 0681 emit d->m_khtml->browserExtension()->openUrlRequest(url, KParts::OpenUrlArguments(), browserArgs); 0682 } 0683 0684 KParts::BrowserExtension::ActionGroupMap KHTMLPopupGUIClient::actionGroups() const 0685 { 0686 return d->actionGroups; 0687 } 0688 0689 void KHTMLPopupGUIClient::slotSaveLinkAs() 0690 { 0691 KIO::MetaData metaData; 0692 metaData["referrer"] = d->m_khtml->referrer(); 0693 saveURL(d->m_khtml->widget(), i18n("Save Link As"), d->m_url, metaData); 0694 } 0695 0696 void KHTMLPopupGUIClient::slotSendImage() 0697 { 0698 QStringList urls; 0699 urls.append(d->m_imageURL.url()); 0700 QString subject = d->m_imageURL.url(); 0701 KToolInvocation::invokeMailer(QString(), QString(), QString(), subject, 0702 QString(), //body 0703 QString(), 0704 urls); // attachments 0705 0706 } 0707 0708 void KHTMLPopupGUIClient::slotSaveImageAs() 0709 { 0710 KIO::MetaData metaData; 0711 metaData["referrer"] = d->m_khtml->referrer(); 0712 saveURL(d->m_khtml->widget(), i18n("Save Image As"), d->m_imageURL, metaData, QString(), 0, d->m_suggestedFilename); 0713 } 0714 0715 void KHTMLPopupGUIClient::slotBlockHost() 0716 { 0717 QString name = d->m_imageURL.scheme() + "://" + d->m_imageURL.host() + "/*"; 0718 KHTMLGlobal::defaultHTMLSettings()->addAdFilter(name); 0719 d->m_khtml->reparseConfiguration(); 0720 } 0721 0722 void KHTMLPopupGUIClient::slotBlockImage() 0723 { 0724 bool ok = false; 0725 0726 QString url = QInputDialog::getText(d->m_khtml->widget(), i18n("Add URL to Filter"), 0727 i18n("Enter the URL:"), QLineEdit::Normal, 0728 d->m_imageURL.url(), &ok); 0729 if (ok) { 0730 KHTMLGlobal::defaultHTMLSettings()->addAdFilter(url); 0731 d->m_khtml->reparseConfiguration(); 0732 } 0733 } 0734 0735 void KHTMLPopupGUIClient::slotBlockIFrame() 0736 { 0737 bool ok = false; 0738 QString url = QInputDialog::getText(d->m_khtml->widget(), i18n("Add URL to Filter"), 0739 i18n("Enter the URL:"), QLineEdit::Normal, 0740 d->m_khtml->url().toString(), &ok); 0741 if (ok) { 0742 KHTMLGlobal::defaultHTMLSettings()->addAdFilter(url); 0743 d->m_khtml->reparseConfiguration(); 0744 } 0745 } 0746 0747 void KHTMLPopupGUIClient::slotCopyLinkLocation() 0748 { 0749 QUrl safeURL(d->m_url); 0750 safeURL.setPassword(QString()); 0751 #ifndef QT_NO_MIMECLIPBOARD 0752 // Set it in both the mouse selection and in the clipboard 0753 QMimeData *mimeData = new QMimeData; 0754 mimeData->setUrls(QList<QUrl>() << safeURL); 0755 QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); 0756 0757 mimeData = new QMimeData; 0758 mimeData->setUrls(QList<QUrl>() << safeURL); 0759 QApplication::clipboard()->setMimeData(mimeData, QClipboard::Selection); 0760 0761 #else 0762 QApplication::clipboard()->setText(safeURL.url()); //FIXME(E): Handle multiple entries 0763 #endif 0764 } 0765 0766 void KHTMLPopupGUIClient::slotStopAnimations() 0767 { 0768 d->m_khtml->stopAnimations(); 0769 } 0770 0771 void KHTMLPopupGUIClient::slotCopyImage() 0772 { 0773 #ifndef QT_NO_MIMECLIPBOARD 0774 QUrl safeURL(d->m_imageURL); 0775 safeURL.setPassword(QString()); 0776 0777 // Set it in both the mouse selection and in the clipboard 0778 QMimeData *mimeData = new QMimeData; 0779 mimeData->setImageData(d->m_pixmap); 0780 mimeData->setUrls(QList<QUrl>() << safeURL); 0781 QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); 0782 0783 mimeData = new QMimeData; 0784 mimeData->setImageData(d->m_pixmap); 0785 mimeData->setUrls(QList<QUrl>() << safeURL); 0786 QApplication::clipboard()->setMimeData(mimeData, QClipboard::Selection); 0787 #else 0788 // qCDebug(KHTML_LOG) << "slotCopyImage called when the clipboard does not support this. This should not be possible."; 0789 #endif 0790 } 0791 0792 void KHTMLPopupGUIClient::slotCopyImageLocation() 0793 { 0794 QUrl safeURL(d->m_imageURL); 0795 safeURL.setPassword(QString()); 0796 #ifndef QT_NO_MIMECLIPBOARD 0797 // Set it in both the mouse selection and in the clipboard 0798 QMimeData *mimeData = new QMimeData; 0799 mimeData->setUrls(QList<QUrl>() << safeURL); 0800 QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); 0801 mimeData = new QMimeData; 0802 mimeData->setUrls(QList<QUrl>() << safeURL); 0803 QApplication::clipboard()->setMimeData(mimeData, QClipboard::Selection); 0804 #else 0805 QApplication::clipboard()->setText(safeURL.url()); //FIXME(E): Handle multiple entries 0806 #endif 0807 } 0808 0809 void KHTMLPopupGUIClient::slotViewImage() 0810 { 0811 d->m_khtml->browserExtension()->createNewWindow(d->m_imageURL); 0812 } 0813 0814 void KHTMLPopupGUIClient::slotReloadFrame() 0815 { 0816 KParts::OpenUrlArguments args = d->m_khtml->arguments(); 0817 args.setReload(true); 0818 args.metaData()["referrer"] = d->m_khtml->pageReferrer(); 0819 // reload document 0820 d->m_khtml->closeUrl(); 0821 d->m_khtml->setArguments(args); 0822 d->m_khtml->openUrl(d->m_khtml->url()); 0823 } 0824 0825 void KHTMLPopupGUIClient::slotFrameInWindow() 0826 { 0827 KParts::OpenUrlArguments args = d->m_khtml->arguments(); 0828 args.metaData()["referrer"] = d->m_khtml->pageReferrer(); 0829 KParts::BrowserArguments browserArgs(d->m_khtml->browserExtension()->browserArguments()); 0830 browserArgs.setForcesNewWindow(true); 0831 emit d->m_khtml->browserExtension()->createNewWindow(d->m_khtml->url(), args, browserArgs); 0832 } 0833 0834 void KHTMLPopupGUIClient::slotFrameInTop() 0835 { 0836 KParts::OpenUrlArguments args = d->m_khtml->arguments(); 0837 args.metaData()["referrer"] = d->m_khtml->pageReferrer(); 0838 KParts::BrowserArguments browserArgs(d->m_khtml->browserExtension()->browserArguments()); 0839 browserArgs.frameName = "_top"; 0840 emit d->m_khtml->browserExtension()->openUrlRequest(d->m_khtml->url(), args, browserArgs); 0841 } 0842 0843 void KHTMLPopupGUIClient::slotFrameInTab() 0844 { 0845 KParts::OpenUrlArguments args = d->m_khtml->arguments(); 0846 args.metaData()["referrer"] = d->m_khtml->pageReferrer(); 0847 KParts::BrowserArguments browserArgs(d->m_khtml->browserExtension()->browserArguments()); 0848 browserArgs.setNewTab(true); 0849 emit d->m_khtml->browserExtension()->createNewWindow(d->m_khtml->url(), args, browserArgs); 0850 } 0851 0852 void KHTMLPopupGUIClient::saveURL(QWidget *parent, const QString &caption, 0853 const QUrl &url, 0854 const QMap<QString, QString> &metadata, 0855 const QString &filter, long cacheId, 0856 const QString &suggestedFilename) 0857 { 0858 QString name = QLatin1String("index.html"); 0859 if (!suggestedFilename.isEmpty()) { 0860 name = suggestedFilename; 0861 } else if (!url.fileName().isEmpty()) { 0862 name = url.fileName(); 0863 } 0864 0865 QUrl destURL; 0866 int query; 0867 do { 0868 query = KMessageBox::PrimaryAction; 0869 // convert filename to URL using fromLocalFile to avoid trouble with ':' in filenames (#184202) 0870 destURL = QFileDialog::getSaveFileUrl(parent, caption, QUrl::fromLocalFile(name), filter); 0871 if (destURL.isLocalFile()) { 0872 QFileInfo info(destURL.toLocalFile()); 0873 if (info.exists()) { 0874 // TODO: use KIO::RenameDlg (shows more information) 0875 query = KMessageBox::warningContinueCancel(parent, i18n("A file named \"%1\" already exists. " "Are you sure you want to overwrite it?", info.fileName()), i18n("Overwrite File?"), KStandardGuiItem::overwrite()); 0876 } 0877 } 0878 } while (query == KMessageBox::Cancel); 0879 0880 if (destURL.isValid()) { 0881 saveURL(parent, url, destURL, metadata, cacheId); 0882 } 0883 } 0884 0885 void KHTMLPopupGUIClient::saveURL(QWidget *parent, const QUrl &url, const QUrl &destURL, 0886 const QMap<QString, QString> &metadata, 0887 long cacheId) 0888 { 0889 if (destURL.isValid()) { 0890 bool saved = false; 0891 if (KHTMLPageCache::self()->isComplete(cacheId)) { 0892 if (destURL.isLocalFile()) { 0893 QSaveFile destFile(destURL.toLocalFile()); 0894 if (destFile.open(QIODevice::WriteOnly)) { 0895 QDataStream stream(&destFile); 0896 KHTMLPageCache::self()->saveData(cacheId, &stream); 0897 destFile.commit(); 0898 saved = true; 0899 } 0900 } else { 0901 // save to temp file, then move to final destination. 0902 QTemporaryFile destFile; 0903 if (destFile.open()) { 0904 QDataStream stream(&destFile); 0905 KHTMLPageCache::self()->saveData(cacheId, &stream); 0906 QUrl url2 = QUrl(); 0907 url2.setPath(destFile.fileName()); 0908 KIO::file_move(url2, destURL, -1, KIO::Overwrite); 0909 saved = true; 0910 } 0911 } 0912 } 0913 if (!saved) { 0914 // DownloadManager <-> konqueror integration 0915 // find if the integration is enabled 0916 // the empty key means no integration 0917 // only use download manager for non-local urls! 0918 bool downloadViaKIO = true; 0919 if (!url.isLocalFile()) { 0920 KConfigGroup cfg = KSharedConfig::openConfig("konquerorrc", KConfig::NoGlobals)->group("HTML Settings"); 0921 QString downloadManger = cfg.readPathEntry("DownloadManager", QString()); 0922 if (!downloadManger.isEmpty()) { 0923 // then find the download manager location 0924 // qCDebug(KHTML_LOG) << "Using: "<<downloadManger <<" as Download Manager"; 0925 QString cmd = QStandardPaths::findExecutable(downloadManger); 0926 if (cmd.isEmpty()) { 0927 QString errMsg = i18n("The Download Manager (%1) could not be found in your $PATH ", downloadManger); 0928 QString errMsgEx = i18n("Try to reinstall it \n\nThe integration with Konqueror will be disabled."); 0929 KMessageBox::detailedError(nullptr, errMsg, errMsgEx); 0930 cfg.writePathEntry("DownloadManager", QString()); 0931 cfg.sync(); 0932 } else { 0933 downloadViaKIO = false; 0934 QUrl cleanDest = destURL; 0935 cleanDest.setPassword(QString()); // don't put password into commandline 0936 cmd += ' ' + KShell::quoteArg(url.url()) + ' ' + 0937 KShell::quoteArg(cleanDest.url()); 0938 // qCDebug(KHTML_LOG) << "Calling command "<<cmd; 0939 KRun::runCommand(cmd, parent->topLevelWidget()); 0940 } 0941 } 0942 } 0943 0944 if (downloadViaKIO) { 0945 KParts::BrowserRun::saveUrlUsingKIO(url, destURL, parent, metadata); 0946 } 0947 } //end if(!saved) 0948 } 0949 } 0950 0951 KHTMLPartBrowserHostExtension::KHTMLPartBrowserHostExtension(KHTMLPart *part) 0952 : KParts::BrowserHostExtension(part) 0953 { 0954 m_part = part; 0955 } 0956 0957 KHTMLPartBrowserHostExtension::~KHTMLPartBrowserHostExtension() 0958 { 0959 } 0960 0961 QStringList KHTMLPartBrowserHostExtension::frameNames() const 0962 { 0963 return m_part->frameNames(); 0964 } 0965 0966 const QList<KParts::ReadOnlyPart *> KHTMLPartBrowserHostExtension::frames() const 0967 { 0968 return m_part->frames(); 0969 } 0970 0971 bool KHTMLPartBrowserHostExtension::openUrlInFrame(const QUrl &url, const KParts::OpenUrlArguments &arguments, const KParts::BrowserArguments &browserArguments) 0972 { 0973 return m_part->openUrlInFrame(url, arguments, browserArguments); 0974 } 0975 0976 KParts::BrowserHostExtension *KHTMLPartBrowserHostExtension::findFrameParent(KParts::ReadOnlyPart 0977 *callingPart, const QString &frame) 0978 { 0979 KHTMLPart *parentPart = m_part->d->findFrameParent(callingPart, frame, nullptr, true /* navigation*/); 0980 if (parentPart) { 0981 return parentPart->browserHostExtension(); 0982 } 0983 return nullptr; 0984 } 0985 0986 // defined in khtml_part.cpp 0987 extern const int KHTML_NO_EXPORT fastZoomSizes[]; 0988 extern const int KHTML_NO_EXPORT fastZoomSizeCount; 0989 0990 KHTMLZoomFactorAction::KHTMLZoomFactorAction(KHTMLPart *part, bool direction, const QString &icon, const QString &text, QObject *parent) 0991 : KSelectAction(text, parent) 0992 { 0993 setIcon(QIcon::fromTheme(icon)); 0994 0995 setToolBarMode(MenuMode); 0996 setToolButtonPopupMode(QToolButton::DelayedPopup); 0997 0998 init(part, direction); 0999 } 1000 1001 void KHTMLZoomFactorAction::init(KHTMLPart *part, bool direction) 1002 { 1003 m_direction = direction; 1004 m_part = part; 1005 1006 // xgettext: no-c-format 1007 addAction(i18n("Default Font Size (100%)")); 1008 1009 int m = m_direction ? 1 : -1; 1010 int ofs = fastZoomSizeCount / 2; // take index of 100% 1011 1012 // this only works if there is an odd number of elements in fastZoomSizes[] 1013 for (int i = m; i != m * (ofs + 1); i += m) { 1014 int num = i * m; 1015 QString numStr = QString::number(num); 1016 if (num > 0) { 1017 numStr.prepend(QLatin1Char('+')); 1018 } 1019 1020 // xgettext: no-c-format 1021 addAction(i18n("%1%", fastZoomSizes[ofs + i])); 1022 } 1023 1024 connect(selectableActionGroup(), SIGNAL(triggered(QAction*)), this, SLOT(slotTriggered(QAction*))); 1025 } 1026 1027 KHTMLZoomFactorAction::~KHTMLZoomFactorAction() 1028 { 1029 } 1030 1031 void KHTMLZoomFactorAction::slotTriggered(QAction *action) 1032 { 1033 int idx = selectableActionGroup()->actions().indexOf(action); 1034 1035 if (idx == 0) { 1036 m_part->setFontScaleFactor(100); 1037 } else { 1038 m_part->setFontScaleFactor(fastZoomSizes[fastZoomSizeCount / 2 + (m_direction ? 1 : -1)*idx]); 1039 } 1040 setCurrentAction(nullptr); 1041 } 1042 1043 KHTMLTextExtension::KHTMLTextExtension(KHTMLPart *part) 1044 : KParts::TextExtension(part) 1045 { 1046 connect(part, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); 1047 } 1048 1049 KHTMLPart *KHTMLTextExtension::part() const 1050 { 1051 return static_cast<KHTMLPart *>(parent()); 1052 } 1053 1054 bool KHTMLTextExtension::hasSelection() const 1055 { 1056 return part()->hasSelection(); 1057 } 1058 1059 QString KHTMLTextExtension::selectedText(Format format) const 1060 { 1061 switch (format) { 1062 case PlainText: 1063 return part()->selectedText(); 1064 case HTML: 1065 return part()->selectedTextAsHTML(); 1066 } 1067 return QString(); 1068 } 1069 1070 QString KHTMLTextExtension::completeText(Format format) const 1071 { 1072 switch (format) { 1073 case PlainText: 1074 return part()->htmlDocument().body().innerText().string(); 1075 case HTML: 1076 return part()->htmlDocument().body().innerHTML().string(); 1077 } 1078 return QString(); 1079 } 1080 1081 //// 1082 1083 KHTMLHtmlExtension::KHTMLHtmlExtension(KHTMLPart *part) 1084 : KParts::HtmlExtension(part) 1085 { 1086 } 1087 1088 QUrl KHTMLHtmlExtension::baseUrl() const 1089 { 1090 return part()->baseURL(); 1091 } 1092 1093 bool KHTMLHtmlExtension::hasSelection() const 1094 { 1095 return part()->hasSelection(); 1096 } 1097 1098 KParts::SelectorInterface::QueryMethods KHTMLHtmlExtension::supportedQueryMethods() const 1099 { 1100 return (KParts::SelectorInterface::SelectedContent | KParts::SelectorInterface::EntireContent); 1101 } 1102 1103 static KParts::SelectorInterface::Element convertDomElement(const DOM::ElementImpl *domElem) 1104 { 1105 KParts::SelectorInterface::Element elem; 1106 elem.setTagName(domElem->tagName().string()); 1107 const DOM::NamedAttrMapImpl *attrMap = domElem->attributes(true /*readonly*/); 1108 if (attrMap) { 1109 for (unsigned i = 0; i < attrMap->length(); ++i) { 1110 const DOM::AttributeImpl &attr = attrMap->attributeAt(i); 1111 elem.setAttribute(attr.localName().string(), attr.value().string()); 1112 // we could have a setAttributeNS too. 1113 } 1114 } 1115 return elem; 1116 } 1117 1118 KParts::SelectorInterface::Element KHTMLHtmlExtension::querySelector(const QString &query, KParts::SelectorInterface::QueryMethod method) const 1119 { 1120 KParts::SelectorInterface::Element element; 1121 1122 // If the specified method is None, return an empty list; similarly 1123 // if the document is null, which may be possible in case of an error 1124 if (method == KParts::SelectorInterface::None || part()->document().isNull()) { 1125 return element; 1126 } 1127 1128 if (!(supportedQueryMethods() & method)) { 1129 return element; 1130 } 1131 1132 switch (method) { 1133 case KParts::SelectorInterface::EntireContent: { 1134 int ec = 0; // exceptions are ignored 1135 WTF::RefPtr<DOM::ElementImpl> domElem = part()->document().handle()->querySelector(query, ec); 1136 element = convertDomElement(domElem.get()); 1137 break; 1138 } 1139 case KParts::SelectorInterface::SelectedContent: 1140 if (part()->hasSelection()) { 1141 DOM::Element domElem = part()->selection().cloneContents().querySelector(query); 1142 element = convertDomElement(static_cast<DOM::ElementImpl *>(domElem.handle())); 1143 } 1144 break; 1145 default: 1146 break; 1147 } 1148 1149 return element; 1150 } 1151 1152 QList<KParts::SelectorInterface::Element> KHTMLHtmlExtension::querySelectorAll(const QString &query, KParts::SelectorInterface::QueryMethod method) const 1153 { 1154 QList<KParts::SelectorInterface::Element> elements; 1155 1156 // If the specified method is None, return an empty list; similarly 1157 // if the document is null, which may be possible in case of an error 1158 if (method == KParts::SelectorInterface::None || part()->document().isNull()) { 1159 return elements; 1160 } 1161 1162 // If the specified method is not supported, return an empty list... 1163 if (!(supportedQueryMethods() & method)) { 1164 return elements; 1165 } 1166 1167 switch (method) { 1168 case KParts::SelectorInterface::EntireContent: { 1169 int ec = 0; // exceptions are ignored 1170 WTF::RefPtr<DOM::NodeListImpl> nodes = part()->document().handle()->querySelectorAll(query, ec); 1171 const unsigned long len = nodes->length(); 1172 elements.reserve(len); 1173 for (unsigned long i = 0; i < len; ++i) { 1174 DOM::NodeImpl *node = nodes->item(i); 1175 if (node->isElementNode()) { // should be always true 1176 elements.append(convertDomElement(static_cast<DOM::ElementImpl *>(node))); 1177 } 1178 } 1179 break; 1180 } 1181 case KParts::SelectorInterface::SelectedContent: 1182 if (part()->hasSelection()) { 1183 DOM::NodeList nodes = part()->selection().cloneContents().querySelectorAll(query); 1184 const unsigned long len = nodes.length(); 1185 for (unsigned long i = 0; i < len; ++i) { 1186 DOM::NodeImpl *node = nodes.item(i).handle(); 1187 if (node->isElementNode()) { 1188 elements.append(convertDomElement(static_cast<DOM::ElementImpl *>(node))); 1189 } 1190 } 1191 } 1192 break; 1193 default: 1194 break; 1195 } 1196 1197 return elements; 1198 } 1199 1200 QVariant KHTMLHtmlExtension::htmlSettingsProperty(HtmlSettingsInterface::HtmlSettingsType type) const 1201 { 1202 if (part()) { 1203 switch (type) { 1204 case KParts::HtmlSettingsInterface::AutoLoadImages: 1205 return part()->autoloadImages(); 1206 case KParts::HtmlSettingsInterface::DnsPrefetchEnabled: 1207 return (part()->dnsPrefetch() == KHTMLPart::DNSPrefetchEnabled); 1208 case KParts::HtmlSettingsInterface::JavaEnabled: 1209 return part()->javaEnabled(); 1210 case KParts::HtmlSettingsInterface::JavascriptEnabled: 1211 return part()->jScriptEnabled(); 1212 case KParts::HtmlSettingsInterface::MetaRefreshEnabled: 1213 return part()->metaRefreshEnabled(); 1214 case KParts::HtmlSettingsInterface::PluginsEnabled: 1215 return part()->pluginsEnabled(); 1216 default: 1217 break; 1218 } 1219 } 1220 return QVariant(); 1221 } 1222 1223 bool KHTMLHtmlExtension::setHtmlSettingsProperty(HtmlSettingsInterface::HtmlSettingsType type, const QVariant &value) 1224 { 1225 KHTMLPart *p = part(); 1226 1227 if (p) { 1228 switch (type) { 1229 case KParts::HtmlSettingsInterface::AutoLoadImages: 1230 p->setAutoloadImages(value.toBool()); 1231 return true; 1232 case KParts::HtmlSettingsInterface::DnsPrefetchEnabled: 1233 p->setDNSPrefetch((value.toBool() ? KHTMLPart::DNSPrefetchEnabled : KHTMLPart::DNSPrefetchDisabled)); 1234 return true; 1235 case KParts::HtmlSettingsInterface::JavaEnabled: 1236 p->setJavaEnabled(value.toBool()); 1237 return true; 1238 case KParts::HtmlSettingsInterface::JavascriptEnabled: 1239 p->setJScriptEnabled(value.toBool()); 1240 return true; 1241 case KParts::HtmlSettingsInterface::MetaRefreshEnabled: 1242 p->setMetaRefreshEnabled(value.toBool()); 1243 return true; 1244 case KParts::HtmlSettingsInterface::PluginsEnabled: 1245 p->setPluginsEnabled(value.toBool()); 1246 return true; 1247 case KParts::HtmlSettingsInterface::UserDefinedStyleSheetURL: { 1248 const QUrl url(value.toUrl()); 1249 if (url.scheme() == QLatin1String("data")) { 1250 const QByteArray data(url.path(QUrl::FullyEncoded).toLatin1()); 1251 if (!data.isEmpty()) { 1252 const int index = data.indexOf(','); 1253 const QByteArray decodedData((index > -1 ? QByteArray::fromBase64(data.mid(index)) : QByteArray())); 1254 p->setUserStyleSheet(QString::fromUtf8(decodedData.constData(), decodedData.size())); 1255 } 1256 } else { 1257 p->setUserStyleSheet(url); 1258 } 1259 return true; 1260 } 1261 default: 1262 break; // Unsupported property... 1263 } 1264 } 1265 1266 return false; 1267 } 1268 1269 KHTMLPart *KHTMLHtmlExtension::part() const 1270 { 1271 return static_cast<KHTMLPart *>(parent()); 1272 } 1273