1 | // program to test the new khtml implementation |
2 | |
3 | #include "testkhtml.h" |
4 | #include "testkhtml.moc" |
5 | |
6 | #include <stdlib.h> |
7 | #include "kapplication.h" |
8 | #include "khtmlview.h" |
9 | #include "html_document.h" |
10 | #include "htmltokenizer.h" |
11 | // to be able to delete a static protected member pointer in kbrowser... |
12 | // just for memory debugging |
13 | #define protected public |
14 | #include "khtml_part.h" |
15 | #undef protected |
16 | #include "misc/loader.h" |
17 | #include <QtGui/QCursor> |
18 | #include <QDomDocument> |
19 | #include <dom_string.h> |
20 | #include "dom/dom2_range.h" |
21 | #include "dom/html_document.h" |
22 | #include "dom/dom_exception.h" |
23 | #include <stdio.h> |
24 | #include "css/cssstyleselector.h" |
25 | #include "html/html_imageimpl.h" |
26 | #include "rendering/render_style.h" |
27 | #include "khtml_global.h" |
28 | #include <kxmlguiwindow.h> |
29 | #include <kcmdlineargs.h> |
30 | #include <ktoggleaction.h> |
31 | #include <kactioncollection.h> |
32 | #include <kicon.h> |
33 | #include "kxmlguifactory.h" |
34 | #include <kfiledialog.h> |
35 | |
36 | int main(int argc, char *argv[]) |
37 | { |
38 | KCmdLineOptions options; |
39 | options.add("+file" , ki18n("URL to open" )); |
40 | |
41 | KCmdLineArgs::init(argc, argv, "testkhtml" , 0, ki18n("Testkhtml" ), |
42 | "1.0" , ki18n("a basic web browser using the KHTML library" )); |
43 | KCmdLineArgs::addCmdLineOptions(options); |
44 | |
45 | KApplication a; |
46 | KCmdLineArgs *args = KCmdLineArgs::parsedArgs( ); |
47 | if ( args->count() == 0 ) { |
48 | KCmdLineArgs::usage(); |
49 | ::exit( 1 ); |
50 | } |
51 | |
52 | new KHTMLGlobal; |
53 | |
54 | KXmlGuiWindow *toplevel = new KXmlGuiWindow(); |
55 | KHTMLPart *doc = new KHTMLPart( toplevel, toplevel, KHTMLPart::BrowserViewGUI ); |
56 | |
57 | Dummy *dummy = new Dummy( doc ); |
58 | QObject::connect( doc->browserExtension(), SIGNAL(openUrlRequest(KUrl,KParts::OpenUrlArguments,KParts::BrowserArguments)), |
59 | dummy, SLOT(slotOpenURL(KUrl,KParts::OpenUrlArguments,KParts::BrowserArguments)) ); |
60 | |
61 | QObject::connect( doc, SIGNAL(completed()), dummy, SLOT(handleDone()) ); |
62 | |
63 | if (args->url(0).url().right(4).toLower() == ".xml" ) { |
64 | KParts::OpenUrlArguments args(doc->arguments()); |
65 | args.setMimeType("text/xml" ); |
66 | doc->setArguments(args); |
67 | } |
68 | |
69 | doc->openUrl( args->url(0) ); |
70 | |
71 | toplevel->setCentralWidget( doc->widget() ); |
72 | toplevel->resize( 800, 600); |
73 | |
74 | QDomDocument d = doc->domDocument(); |
75 | QDomElement = d.documentElement().firstChild().childNodes().item( 2 ).toElement(); |
76 | QDomElement e = d.createElement( "action" ); |
77 | e.setAttribute( "name" , "debugRenderTree" ); |
78 | viewMenu.appendChild( e ); |
79 | e = d.createElement( "action" ); |
80 | e.setAttribute( "name" , "debugDOMTree" ); |
81 | viewMenu.appendChild( e ); |
82 | e = d.createElement( "action" ); |
83 | e.setAttribute( "name" , "debugDoBenchmark" ); |
84 | viewMenu.appendChild( e ); |
85 | |
86 | QDomElement toolBar = d.documentElement().firstChild().nextSibling().toElement(); |
87 | e = d.createElement( "action" ); |
88 | e.setAttribute( "name" , "editable" ); |
89 | toolBar.insertBefore( e, toolBar.firstChild() ); |
90 | e = d.createElement( "action" ); |
91 | e.setAttribute( "name" , "navigable" ); |
92 | toolBar.insertBefore( e, toolBar.firstChild() ); |
93 | e = d.createElement( "action" ); |
94 | e.setAttribute( "name" , "reload" ); |
95 | toolBar.insertBefore( e, toolBar.firstChild() ); |
96 | e = d.createElement( "action" ); |
97 | e.setAttribute( "name" , "print" ); |
98 | toolBar.insertBefore( e, toolBar.firstChild() ); |
99 | |
100 | KAction *action = new KAction(KIcon("view-refresh" ), "Reload" , doc ); |
101 | doc->actionCollection()->addAction( "reload" , action ); |
102 | QObject::connect(action, SIGNAL(triggered(bool)), dummy, SLOT(reload())); |
103 | action->setShortcut(Qt::Key_F5); |
104 | |
105 | KAction *bench = new KAction( KIcon(), "Benchmark..." , doc ); |
106 | doc->actionCollection()->addAction( "debugDoBenchmark" , bench ); |
107 | QObject::connect(bench, SIGNAL(triggered(bool)), dummy, SLOT(doBenchmark())); |
108 | |
109 | KAction *kprint = new KAction(KIcon("document-print" ), "Print" , doc ); |
110 | doc->actionCollection()->addAction( "print" , kprint ); |
111 | QObject::connect(kprint, SIGNAL(triggered(bool)), doc->browserExtension(), SLOT(print())); |
112 | kprint->setEnabled(true); |
113 | KToggleAction *ta = new KToggleAction( KIcon("edit-rename" ), "Navigable" , doc ); |
114 | doc->actionCollection()->addAction( "navigable" , ta ); |
115 | ta->setShortcuts( KShortcut() ); |
116 | ta->setChecked(doc->isCaretMode()); |
117 | QWidget::connect(ta, SIGNAL(toggled(bool)), dummy, SLOT(toggleNavigable(bool))); |
118 | ta = new KToggleAction( KIcon("document-properties" ), "Editable" , doc ); |
119 | doc->actionCollection()->addAction( "editable" , ta ); |
120 | ta->setShortcuts( KShortcut() ); |
121 | ta->setChecked(doc->isEditable()); |
122 | QWidget::connect(ta, SIGNAL(toggled(bool)), dummy, SLOT(toggleEditable(bool))); |
123 | toplevel->guiFactory()->addClient( doc ); |
124 | |
125 | doc->setJScriptEnabled(true); |
126 | doc->setJavaEnabled(true); |
127 | doc->setPluginsEnabled( true ); |
128 | doc->setURLCursor(QCursor(Qt::PointingHandCursor)); |
129 | a.setTopWidget(doc->widget()); |
130 | QWidget::connect(doc, SIGNAL(setWindowCaption(QString)), |
131 | doc->widget()->topLevelWidget(), SLOT(setCaption(QString))); |
132 | doc->widget()->show(); |
133 | toplevel->show(); |
134 | doc->view()->viewport()->show(); |
135 | doc->view()->widget()->show(); |
136 | |
137 | |
138 | int ret = a.exec(); |
139 | return ret; |
140 | } |
141 | |
142 | void Dummy::doBenchmark() |
143 | { |
144 | KConfigGroup settings(KGlobal::config(), "bench" ); |
145 | results.clear(); |
146 | |
147 | QString directory = KFileDialog::getExistingDirectory(settings.readPathEntry("path" , QString()), m_part->view(), |
148 | QString::fromLatin1("Please select directory with tests" )); |
149 | |
150 | if (!directory.isEmpty()) { |
151 | settings.writePathEntry("path" , directory); |
152 | KGlobal::config()->sync(); |
153 | |
154 | QDir dirListing(directory, "*.html" ); |
155 | for (unsigned i = 0; i < dirListing.count(); ++i) { |
156 | filesToBenchmark.append(dirListing.absoluteFilePath(dirListing[i])); |
157 | } |
158 | } |
159 | |
160 | benchmarkRun = 0; |
161 | |
162 | if (!filesToBenchmark.isEmpty()) |
163 | nextRun(); |
164 | } |
165 | |
166 | const int COLD_RUNS = 2; |
167 | const int HOT_RUNS = 6; |
168 | |
169 | void Dummy::nextRun() |
170 | { |
171 | if (benchmarkRun == (COLD_RUNS + HOT_RUNS)) { |
172 | filesToBenchmark.removeFirst(); |
173 | benchmarkRun = 0; |
174 | } |
175 | |
176 | if (!filesToBenchmark.isEmpty()) { |
177 | loadTimer.start(); |
178 | m_part->openUrl(filesToBenchmark[0]); |
179 | } else { |
180 | //Generate HTML for report. |
181 | m_part->begin(); |
182 | m_part->write("<html><body><table border=1>" ); |
183 | |
184 | for (QMap<QString, QList<int> >::iterator i = results.begin(); i != results.end(); ++i) { |
185 | m_part->write("<tr><td>" + i.key() + "</td>" ); |
186 | QList<int> timings = i.value(); |
187 | int total = 0; |
188 | for (int pos = 0; pos < timings.size(); ++pos) { |
189 | int t = timings[pos]; |
190 | if (pos < COLD_RUNS) |
191 | m_part->write(QString::fromLatin1("<td>(Cold):" ) + QString::number(t) + "</td>" ); |
192 | else { |
193 | total += t; |
194 | m_part->write(QString::fromLatin1("<td><i>" ) + QString::number(t) + "</i></td>" ); |
195 | } |
196 | } |
197 | |
198 | m_part->write(QString::fromLatin1("<td>Average:<b>" ) + QString::number(double(total) / HOT_RUNS) + "</b></td>" ); |
199 | |
200 | m_part->write("</tr>" ); |
201 | } |
202 | |
203 | m_part->end(); |
204 | } |
205 | } |
206 | |
207 | void Dummy::handleDone() |
208 | { |
209 | if (filesToBenchmark.isEmpty()) return; |
210 | |
211 | results[filesToBenchmark[0]].append(loadTimer.elapsed()); |
212 | ++benchmarkRun; |
213 | QTimer::singleShot(100, this, SLOT(nextRun())); |
214 | } |
215 | |