htmlquotecolorer.cpp 4.82 KB
Newer Older
Andras Mantia's avatar
Andras Mantia committed
1
/* Copyright 2009 Thomas McGuire <mcguire@kde.org>
Torgny Nyblom's avatar
Torgny Nyblom committed
2
             2009 Torgny Nyblom <nyblom@kde.org>
Andras Mantia's avatar
Andras Mantia committed
3

Thomas McGuire's avatar
Thomas McGuire committed
4
5
6
7
8
9
10
11
12
   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) version 3 or any later version
   accepted by the membership of KDE e.V. (or its successor approved
   by the membership of KDE e.V.), which shall act as a proxy
   defined in Section 14 of version 3 of the license.

   This program is distributed in the hope that it will be useful,
Andras Mantia's avatar
Andras Mantia committed
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Thomas McGuire's avatar
Thomas McGuire committed
14
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
Andras Mantia's avatar
Andras Mantia committed
16

Thomas McGuire's avatar
Thomas McGuire committed
17
18
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
Andras Mantia's avatar
Andras Mantia committed
19
*/
Marc Mutz's avatar
Marc Mutz committed
20
21
#include <config-messageviewer.h>

Andras Mantia's avatar
Andras Mantia committed
22
23
#include "htmlquotecolorer.h"

24
25
#include <KDebug>

26
#ifndef KDEPIM_NO_WEBKIT
27
28
#include <QWebPage>
#include <QWebFrame>
29
#include <QWebElement>
30
#endif
31
32

using namespace MessageViewer;
Andras Mantia's avatar
Andras Mantia committed
33

Andras Mantia's avatar
Andras Mantia committed
34
HTMLQuoteColorer::HTMLQuoteColorer()
Andras Mantia's avatar
Andras Mantia committed
35
36
37
38
39
{
}

QString HTMLQuoteColorer::process( const QString &htmlSource )
{
40
#ifndef KDEPIM_NO_WEBKIT
41
42
  // Create a DOM Document from the HTML source
  QWebPage page(0);
43
44
45
46
  page.settings()->setAttribute( QWebSettings::JavascriptEnabled, false );
  page.settings()->setAttribute( QWebSettings::JavaEnabled, false );
  page.settings()->setAttribute( QWebSettings::PluginsEnabled, false );

Laurent Montel's avatar
Laurent Montel committed
47
48
  page.settings()->setAttribute( QWebSettings::AutoLoadImages, false );

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
  QWebFrame *frame = page.mainFrame();
  frame->setHtml( htmlSource );
  
  QString script(
   "mIsQuotedLine = false;\n"
   "mIsFirstTextNodeInLine = true;\n"
   "mQuoteColors = new Array();\n"
   "mQuoteColors[0] = \"" + mQuoteColors[0].name() + "\";\n"
   "mQuoteColors[1] = \"" + mQuoteColors[1].name() + "\";\n"
   "mQuoteColors[2] = \"" + mQuoteColors[2].name() + "\";\n"

   "processNode( document.documentElement );\n"

   "function processNode( node ) {\n"
  // Below, we determine if the current text node should be quote colored by keeping track of"
  // linebreaks and whether this text node is the first one."
  "  var textContent = node.textContent;\n"
  "  var isTextNode = !textContent.length == 0 && !node.hasChildNodes();\n"
  "  if ( isTextNode ) {\n"
  "   if ( mIsFirstTextNodeInLine ) {\n"
  "     if ( textContent.charAt( 0 ) ==  '>' || textContent.charAt( 0 ) == '|' ) {\n"
  "       mIsQuotedLine = true;\n"
  "       currentQuoteLength = quoteLength( textContent ) - 1;\n"
  "     }\n"
  "     else {\n"
  "       mIsQuotedLine = false;\n"
  "     }\n"
  "    }\n"
  
  // All subsequent text nodes are not the first ones anymore"
  "    mIsFirstTextNodeInLine = false;\n"
  "  }\n"

  "  var nodeName = node.nodeName.toLowerCase();\n"
  "  var lineBreakNodes = new Array();\n"
  "  lineBreakNodes[0] = \"br\"\n"
  "  lineBreakNodes[1] = \"p\"\n"
  "  lineBreakNodes[2] = \"div\"\n"
  "  lineBreakNodes[3] = \"ul\"\n"
  "  lineBreakNodes[4] = \"ol\"\n"
  "  lineBreakNodes[5] = \"li\"\n"

  "  for( i = 0; i < lineBreakNodes.length; lineBreakNodes++) {\n"
  "    if ( lineBreakNodes[i] == nodeName ) {\n"
  "      mIsFirstTextNodeInLine = true;\n"
  "      break;\n"
  "    }\n"
  "  }\n"

  "  var returnNode = node;\n"
  "  var fontTagAdded = false;\n"
  "  if ( mIsQuotedLine && isTextNode ) {\n"
  
  // Ok, we are in a line that should be quoted, so create a font node for the color and replace"
  // the current node with it."
  "    var font = node.ownerDocument.createElement( \"font\" );\n"
  "    font.setAttribute( \"color\", mQuoteColors[ currentQuoteLength ] );\n"
  "    node.parentNode.replaceChild( font, node );\n"
  "    font.appendChild( node );\n"
  "    returnNode = font;\n"
  "    fontTagAdded = true;\n"
  "  }\n"
  
  // Process all child nodes, but only if we are didn't add those child nodes itself, as otherwise"
  // we'll go into an infinite recursion."
  "  if ( !fontTagAdded ) {\n"
  "    var childNode = node.firstChild;\n"
  "    while ( childNode ) {\n"
  "      childNode = processNode( childNode );\n"
  "      childNode = childNode.nextSibling;\n"
  "    }\n"
  "  }\n"
  "  return returnNode;\n"
  "}\n"

  "function quoteLength( line )\n"
  "{\n"
  "  line = line.replace(  \"\\s\", \"\" ).replace( '|', '>' );\n"
  "  if ( line.substr( 0, 3 ) == \">>>\" ) return 3;\n"
  "  if ( line.substr( 0, 2 ) == \">>\" ) return 2;\n"
  "  if ( line.substr( 0, 1 ) == '>' ) return 1;\n"
  "  return 0;\n"
  "}\n");

Torgny Nyblom's avatar
Torgny Nyblom committed
133
134
  frame->evaluateJavaScript( script );
  const QWebElement body = frame->documentElement().findFirst("body");
135
136
  
  return body.toInnerXml();
137
138
139
#else
  return htmlSource;
#endif
Andras Mantia's avatar
Andras Mantia committed
140
141
}

142
void HTMLQuoteColorer::setQuoteColor( unsigned int level, const QColor& color )
Andras Mantia's avatar
Andras Mantia committed
143
144
145
146
{
  if ( level < 3 )
    mQuoteColors[level] = color;
}
147