// -*- mode: c++; c-basic-offset: 4 -*- /* Copyright (C) 2006 Daniele Galdi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Project related */ #include "adblock.h" #include "adblockdialogue.h" /* Kde related */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace DOM; #include #include #include typedef KGenericFactory AdBlockFactory; K_EXPORT_COMPONENT_FACTORY( libadblock, AdBlockFactory( "adblock" ) ) AdBlock::AdBlock(QObject *parent, const char *name, const QStringList &) : KParts::Plugin(parent, name), m_label(0), m_menu(0) { m_part = dynamic_cast(parent); if(!m_part) { kdDebug() << "couldn't get KHTMLPart" << endl; return; } m_menu = new KPopupMenu(m_part->widget()); m_menu->insertTitle(i18n("Adblock")); m_menu->insertItem(i18n("Configure"), this, SLOT(showKCModule())); m_menu->insertItem(i18n("Show Elements"), this, SLOT(showDialogue())); connect(m_part, SIGNAL(completed()), this, SLOT(initLabel())); } AdBlock::~AdBlock() { KParts::StatusBarExtension *statusBarEx = KParts::StatusBarExtension::childObject(m_part); if (!statusBarEx) { kdDebug() << "couldn't get KParts::StatusBarExtension" << endl; return; } statusBarEx->removeStatusBarItem(m_label); delete m_menu; } void AdBlock::initLabel() { if (m_label) return; KParts::StatusBarExtension *statusBarEx = KParts::StatusBarExtension::childObject(m_part); if (!statusBarEx) { kdDebug() << "couldn't get KParts::StatusBarExtension" << endl; return; } m_label = new KURLLabel(statusBarEx->statusBar()); KIconLoader *loader = instance()->iconLoader(); m_label->setFixedHeight(loader->currentSize(KIcon::Small)); m_label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); m_label->setUseCursor(false); m_label->setPixmap(loader->loadIcon("filter", KIcon::Small)); statusBarEx->addStatusBarItem(m_label, 0, false); connect(m_label, SIGNAL(leftClickedURL()), this, SLOT(showDialogue())); connect(m_label, SIGNAL(rightClickedURL()), this, SLOT(contextMenu())); } void AdBlock::showDialogue() { if (!m_part->settings()->isAdFilterEnabled()) { KMessageBox::error(0, i18n("Please enable Konqueror's Adblock"), i18n("Adblock disabled")); return; } AdElementList elements; fillBlockableElements(elements); AdBlockDlg *dialogue = new AdBlockDlg(m_part->widget(), elements); connect(dialogue, SIGNAL( notEmptyFilter(const QString&) ), this, SLOT( addAdFilter(const QString&) )); connect(dialogue, SIGNAL( cancelClicked() ), dialogue, SLOT( delayedDestruct() )); connect(dialogue, SIGNAL( closeClicked() ), dialogue, SLOT( delayedDestruct() )); dialogue->show(); } void AdBlock::showKCModule() { KCMultiDialog* dialogue = new KCMultiDialog(m_part->widget()); dialogue->addModule("khtml_filter"); connect(dialogue, SIGNAL( cancelClicked() ), dialogue, SLOT( delayedDestruct() )); connect(dialogue, SIGNAL( closeClicked() ), dialogue, SLOT( delayedDestruct() )); dialogue->show(); } void AdBlock::contextMenu() { m_menu->popup(QCursor::pos()); } void AdBlock::fillBlockableElements(AdElementList &elements) { fillWithHtmlTag(elements, "script", "src", "SCRIPT"); fillWithHtmlTag(elements, "embed" , "src", "OBJECT"); fillWithHtmlTag(elements, "object", "src", "OBJECT"); fillWithImages(elements); const KHTMLSettings *settings = m_part->settings(); AdElementList::iterator it; for ( it = elements.begin(); it != elements.end(); ++it ) { AdElement &element = (*it); if (settings->isAdFiltered( element.url() )) { element.setBlocked(true); } } } void AdBlock::fillWithImages(AdElementList &elements) { HTMLDocument htmlDoc = m_part->htmlDocument(); HTMLCollection images = htmlDoc.images(); for (unsigned int i = 0; i < images.length(); i++) { HTMLImageElement image = static_cast( images.item(i) ); DOMString src = image.src(); QString url = htmlDoc.completeURL(src).string(); if (!url.isEmpty() && url != m_part->baseURL().url()) { AdElement element(url, "image", "IMG", false); if (!elements.contains( element )) elements.append( element); } } } void AdBlock::fillWithHtmlTag(AdElementList &elements, const DOMString &tagName, const DOMString &attrName, const QString &category) { Document doc = m_part->document(); NodeList nodes = doc.getElementsByTagName(tagName); for (unsigned int i = 0; i < nodes.length(); i++) { Node node = nodes.item(i); Node attr = node.attributes().getNamedItem(attrName); DOMString src = attr.nodeValue(); if (src.isNull()) continue; QString url = doc.completeURL(src).string(); if (!url.isEmpty() && url != m_part->baseURL().url()) { AdElement element(url, tagName.string(), category, false); if (!elements.contains( element )) elements.append( element); } } } void AdBlock::addAdFilter(const QString &url) { //FIXME hackish KHTMLSettings *settings = const_cast(m_part->settings()); settings->addAdFilter(url); } // ---------------------------------------------------------------------------- AdElement::AdElement() : m_url(0), m_category(0), m_type(0), m_blocked(false) {} AdElement::AdElement(const QString &url, const QString &category, const QString &type, bool blocked) : m_url(url), m_category(category), m_type(type), m_blocked(blocked) {} AdElement &AdElement::operator=(const AdElement &obj) { m_blocked = obj.m_blocked; m_url = obj.m_url; m_category = obj.m_category; m_type = obj.m_type; return *this; } bool AdElement::operator==(const AdElement &obj) { return m_url == obj.m_url; } bool AdElement::isBlocked() const { return m_blocked; } void AdElement::setBlocked(bool blocked) { m_blocked = blocked; } const QString &AdElement::url() const { return m_url; } const QString &AdElement::category() const { return m_category; } const QString &AdElement::type() const { return m_type; } #include "adblock.moc"