summaryrefslogtreecommitdiffstats
path: root/konq-plugins/adblock/adblock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'konq-plugins/adblock/adblock.cpp')
-rw-r--r--konq-plugins/adblock/adblock.cpp268
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"