diff options
Diffstat (limited to 'konq-plugins/adblock/adblock.cpp')
-rw-r--r-- | konq-plugins/adblock/adblock.cpp | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/konq-plugins/adblock/adblock.cpp b/konq-plugins/adblock/adblock.cpp new file mode 100644 index 0000000..30878fd --- /dev/null +++ b/konq-plugins/adblock/adblock.cpp @@ -0,0 +1,268 @@ +// -*- mode: c++; c-basic-offset: 4 -*- +/* + Copyright (C) 2006 Daniele Galdi <[email protected]> + + 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 <kgenericfactory.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <klibloader.h> +#include <kparts/statusbarextension.h> +#include <khtml_part.h> +#include <khtml_settings.h> +#include <kstatusbar.h> +#include <kurllabel.h> +#include <kdialogbase.h> +#include <kurl.h> +#include <kconfig.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <kpopupmenu.h> +#include <kcmultidialog.h> +#include <klocale.h> +#include <dom/html_document.h> +#include <dom/html_image.h> +#include <dom/html_inline.h> +#include <dom/html_misc.h> +#include <dom/html_element.h> +#include <dom/dom_doc.h> +#include <dom/dom_node.h> +using namespace DOM; + +#include <qpixmap.h> +#include <qcursor.h> +#include <qregexp.h> + +typedef KGenericFactory<AdBlock> 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<KHTMLPart *>(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<HTMLImageElement>( 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<KHTMLSettings *>(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" |