1 //=============================================================================
2 //
3 // File : KvsObject_webView.cpp
4 // Creation date : Wed Mar 9 23:34:48 CEST 2011
5 // by Alessandro Carbone(Noldor)
6 //
7 // This file is part of the KVIrc IRC client distribution
8 // Copyright (C) 2011 Alessandro Carbone (elfonol at gmail dot com)
9 //
10 // This program is FREE software. You can redistribute it and/or
11 // modify it under the terms of the GNU General Public License
12 // as published by the Free Software Foundation; either version 2
13 // of the License, or (at your option) any later version.
14 //
15 // This program is distributed in the HOPE that it will be USEFUL,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 // See the GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program. If not, write to the Free Software Foundation,
22 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 //
24 //=============================================================================
25 //
26
27 #include "kvi_settings.h"
28 #include "kvi_debug.h"
29 #include "KvsObject_webView.h"
30 #include "KvsObject_pixmap.h"
31 #include "KviError.h"
32 #include "KviLocale.h"
33
34 #include <QMenu>
35
36 #if defined(COMPILE_WEBKIT_SUPPORT)
37 #include <QWebView>
38 #include <QWebSettings>
39 #include <QWebElement>
40 #include <QNetworkRequest>
41 #include <QNetworkReply>
42 #include <QPixmap>
43 #include <QFile>
44 #include <QSize>
45 #include <QPoint>
46 #include <QVariant>
47 #include <QToolTip>
48
49 static int g_iDownloadId = 1;
KviKvsDownloadHandler(KvsObject_webView * pParent,QFile * pFile,QNetworkReply * pNetReply,int iId)50 KviKvsDownloadHandler::KviKvsDownloadHandler(KvsObject_webView * pParent, QFile * pFile, QNetworkReply * pNetReply, int iId)
51 : QObject(pParent)
52 {
53
54 m_Id = iId;
55 m_pParentScript = pParent;
56 m_pReply = pNetReply;
57 m_pFile = pFile;
58 connect(m_pReply, SIGNAL(finished()), this, SLOT(slotReplyFinished()));
59 connect(m_pReply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
60 }
61
slotReplyFinished()62 void KviKvsDownloadHandler::slotReplyFinished()
63 {
64 KviKvsVariantList params(new KviKvsVariant((kvs_int_t)m_Id));
65 m_pParentScript->callFunction(m_pParentScript, "downloadCompletedEvent", ¶ms);
66 m_pFile->close();
67 delete m_pFile;
68 m_pFile = nullptr;
69 m_pReply->deleteLater();
70 m_pReply = nullptr;
71 this->deleteLater();
72 }
73
~KviKvsDownloadHandler()74 KviKvsDownloadHandler::~KviKvsDownloadHandler()
75 {
76 if(m_pFile)
77 {
78 m_pFile->close();
79 delete m_pFile;
80 m_pFile = nullptr;
81 }
82 if(m_pReply)
83 {
84 delete m_pReply;
85 m_pReply = nullptr;
86 }
87 }
slotReadyRead()88 void KviKvsDownloadHandler::slotReadyRead()
89 {
90 QVariant vSize = m_pReply->header(QNetworkRequest::ContentLengthHeader);
91 int iSize = 0;
92 if(!vSize.isNull())
93 {
94 bool bOk;
95 iSize = vSize.toInt(&bOk);
96 }
97
98 QByteArray bytes = m_pReply->readAll();
99 KviKvsVariantList params(new KviKvsVariant((kvs_int_t)bytes.count()),
100 new KviKvsVariant((kvs_int_t)m_Id), new KviKvsVariant((kvs_int_t)iSize));
101 m_pParentScript->callFunction(m_pParentScript, "downloadProgressEvent", ¶ms);
102 m_pFile->write(bytes);
103 }
104
105 const char * const webattributes_tbl[] = {
106 "JavascriptEnabled",
107 "PluginsEnabled",
108 "JavascriptCanOpenWindows",
109 "JavascriptCanAccessClipboard",
110 "ZoomTextOnly",
111 "LocalContentCanAccessFileUrls"
112 };
113
114 const QWebSettings::WebAttribute webattributes_cod[] = {
115 QWebSettings::JavascriptEnabled,
116 QWebSettings::PluginsEnabled,
117 QWebSettings::JavascriptCanOpenWindows,
118 QWebSettings::JavascriptCanAccessClipboard,
119 QWebSettings::ZoomTextOnly,
120 QWebSettings::LocalContentCanAccessFileUrls
121 };
122
123 const char * const findflag_tbl[] = {
124 "FindBackward",
125 "FindCaseSensitively",
126 "FindWrapsAroundDocument",
127 "HighlightAllOccurrences"
128 };
129
130 const QWebPage::FindFlag findflag_cod[] = {
131 QWebPage::FindBackward,
132 QWebPage::FindCaseSensitively,
133 QWebPage::FindWrapsAroundDocument,
134 QWebPage::HighlightAllOccurrences
135 };
136
137 const QWebPage::WebAction actions_cod[] = {
138 QWebPage::OpenLink,
139 QWebPage::DownloadLinkToDisk,
140 QWebPage::CopyLinkToClipboard,
141 QWebPage::OpenImageInNewWindow,
142 QWebPage::DownloadImageToDisk,
143 QWebPage::CopyImageToClipboard,
144 QWebPage::Back,
145 QWebPage::Forward,
146 QWebPage::Stop,
147 QWebPage::Reload,
148 QWebPage::Cut,
149 QWebPage::Copy,
150 QWebPage::Paste,
151 QWebPage::InspectElement,
152 QWebPage::SelectAll
153 };
154
155 const char * const actions_tbl[] = {
156 "OpenLink",
157 "DownloadLinkToDisk",
158 "CopyLinkToClipboard",
159 "OpenImageInNewWindow",
160 "DownloadImageToDisk",
161 "CopyImageToClipboard",
162 "Back",
163 "Forward",
164 "Stop",
165 "Reload",
166 "Cut",
167 "Copy",
168 "Paste",
169 "InspectElement",
170 "SelectAll"
171 };
172
173 #define webattributes_num (sizeof(webattributes_tbl) / sizeof(webattributes_tbl[0]))
174 #define findflag_num (sizeof(findflag_tbl) / sizeof(findflag_tbl[0]))
175 #define actions_num (sizeof(actions_tbl) / sizeof(actions_tbl[0]))
176
177 /*
178 @doc: webview
179 @keyterms:
180 An embedded webview widget,
181 @title:
182 webview
183 @type:
184 class
185 @short:
186 Provides web support in a widget using webkit.
187 @inherits:
188 [class]object[/class]
189 [class]widget[/class]
190 @description:
191 Provides an embedded web browser using webkit. Page structure can be managed by web element's unique identifiers.
192 @functions:
193 !fn: $load(<url:string>)
194 Sets the current URL for the webView and starts loading it
195 !fn: $setHtml(<html_code:string>,[<baseurl:string>])
196 Sets the content of the web view to the specified <html_code>.
197 External objects such as stylesheets or images referenced in the HTML document are located relative to <baseurl>.
198 The html is loaded immediately; external objects are loaded asynchronously.
199 !fn: $findText(<txt:string>,[flag 1,flag 2,..;string])
200 Finds the specified string, in the page, using the given options.
201 Valid flags are:
202 [pre]
203 FindBackward - Searches backwards instead of forwards;
204 FindCaseSensitively - Changes the behaviour to a case sensitive find operation.
205 FindWrapsAroundDocument - Restart from the beginning of the document if the end was reached and the text was not found.
206 HighlightAllOccurrences - Highlights all existing occurrences.
207 [/pre]
208 !fn: <array> $frames()
209 Returns an array containing the names of the document frames.
210 !fn: appendWebViewActionToMenu(<menu:h_object>,<webview_action:string>,[<icon_identifier>])
211 !fn: <id:integer> $firstChild(<element_id:integer>)
212 Return the identifier of element's first child.
213 !fn: <array> $findAll(<element_id:integer>,<query:string>)
214 Searches for all the elements named <query> and stores them in an array of element's identifiers.
215 !fn: <id:integer> $findFirst(<element_id:integer>,<query:string>)
216 Searches for the first element named <query>; returns the identifier.
217 !fn: <id:integer> $parentElement(<element_id:integer>,)
218 Returns the parent of <element_id>.
219 !fn: <id:integer> $nextSibling(<element_id>)
220 Returns the element just after <element_id>.
221 !fn: $appendInside(<element_id>,<html_code>)
222 !fn: $appendOutside(<element_id>,<html_code>)
223 !fn: <string> $elementTagName(<element_id>)
224 Returns the tag name of the <element_id>.
225 !fn: <id:integer> $getDocumentElement([frame_name:string])
226 Return as unique identifier the document element of the frame [frame_name].
227 If no value has been specified for [frame_name], the main frame of the page will be used.
228 !fn: string $attributeNames(<element_id>)
229 Returns a comma-separated list of the attribute names set on element <element_id>.
230 !fn: string $attribute(<element_id>,<name:string>)
231 Returns the value of the attribute <name> for element <element_id>.
232 !fn: setStyleProperty(<element_id>,<name:string>,<value:string>)
233 Sets the value of the inline style on element <element_id> with the given name to <value> .
234 In order to ensure that the value will be applied, you may have to append "!important" to the value.
235 !fn: <value:string> styleProperty(<element_id>,<name:string>,<style_resolve_strategy:string>)
236 Returns the value of the style with the given name using the specified strategy. If a style with name does not exist, an empty string is returned.
237 Possible value for <style_resolve_strategy> are:
238 [pre]
239 CascadedStyle - the property's value is determined using the rules defined in the document's stylesheet. [b]This is the default strategy[/b].
240 InlineStyle - the property's value is determined by element definition, without respecting CSS rules.
241 ComputedStyle - the property's value is determined by the style property resolved from the environment.
242 [/pre]
243 !fn: pixmap $makePreview()
244 Returns a 212x142 thumbnail of the current webView constants.
245 The returned object is an instance of the pixmap class.
246 !fn: string $toPlainText(<element_id>)
247 Returns the string representation of element <element_id>.
248 !fn: string $setPlainText(<element_id>)
249 Set the string representation of the element <element_id>.
250 !fn: $setElementAttribute(<element_id>,<name:string>,<value:string>)
251 Sets the attribute <name> with value <value> to the element <element_id>.
252 !fn: $setWebSetting(<name:string>,<value:bool>)
253 Enables or disables the <name> setting depending on <value>.
254 Valid settings name: JavascriptEnabled, PluginsEnabled, JavascriptCanOpenWindows, JavascriptCanAccessClipboard, ZoomTextOnly, LocalContentCanAccessFileUrls.
255 !fn: $removeFromDocument(<element_id>)
256 Removes the element <element_id> from the document.
257 !fn: $removeClass(<element_id>,<class_name:string>)
258 Removes a class from the element <element_id>.
259 !fn: string $classes(<element_id>)
260 Returns a comma-separated list of classes set on the element <element_id>.
261 !fn: $setLinkDelegationPolicy(<policy:string>)
262 Sets the link delegation policy: what happens when the users click on a link. Valid values:
263 [br] DontDelegateLinks: No links are delegated. Instead, webView tries to handle them all.
264 [br] DelegateExternalLinks: When activating links that point to documents not stored on the local filesystem or an equivalent then $linkClickedEvent() is executed.
265 [br] DelegateAllLinks: Whenever a link is activated the $linkClickedEvent() is executed.
266 !fn: $linkClickedEvent()
267 This function can be called when the user clicks on a link, depending no the current link delegation policy.
268 The argument of the function is the URL that has been clicked.[br]
269 The default implementation emits the [classfnc:webview]$linkClicked[/classfnc]() signal.
270 !fn: $loadStartedEvent()
271 This function is called when the load of the page has started.
272 The default implementation emits the [classfnc:webview]$loadStarted[/classfnc]() signal.
273 !fn: $loadProgressEvent()
274 This function can be called during the page load progress.
275 The argument of the function is an int value that represent the loading progress status, ranging from 0 to 100.[br]
276 The default implementation emits the [classfnc:webview]$loadProgress[/classfnc]() signal.
277 !fn: $loadFinishedEvent()
278 This function is called when the load of the page has finished.
279 The argument of the function is a bool value that is true if the page has been loaded successfully, false otherwise.[br]
280 The default implementation emits the [classfnc:webview]$loadFinished[/classfnc]() signal.
281 !fn: $downloadRequestEvent()
282 This function is called when the user tries to download a file.
283 The argument of the function is the URL of the file.[br]
284 You should return a valid path in the filesystem where to save the file.[br]
285 The default implementation emits the [classfnc:webview]$downloadRequest[/classfnc]() signal.
286 !fn: $downloadProgressEvent()
287 This function can be called during the download of a file.
288 Three integer arguments are passed to this function: the number of downloaded bytes, the download ID, the size of the remove file (if known).
289 The default implementation emits the [classfnc:webview]$downloadProgress[/classfnc]() signal.
290 !fn: $downloadCompletedEvent()
291 This function can be called when a file download finishes.
292 The argument of the function is the an integer value containing the download ID.
293 The default implementation emits the [classfnc:webview]$downloadCompleted[/classfnc]() signal.
294 @signals:
295 !sg: linkClicked()
296 This signal is emitted by the default implementation of [classfnc:webview]linkClickedEvent[/classfnc]().
297 !sg: loadStarted()
298 This signal is emitted by the default implementation of [classfnc:webview]loadStartedEvent[/classfnc]().
299 !sg: loadProgress()
300 This signal is emitted by the default implementation of [classfnc:webview]loadProgressEvent[/classfnc]().
301 !sg: loadFinished()
302 This signal is emitted by the default implementation of [classfnc:webview]loadFinishedEvent[/classfnc]().
303 !sg: downloadRequest()
304 This signal is emitted by the default implementation of [classfnc:webview]downloadRequestEvent[/classfnc]().
305 !sg: downloadProgress()
306 This signal is emitted by the default implementation of [classfnc:webview]downloadProgressEvent[/classfnc]().
307 !sg: downloadCompleted()
308 This signal is emitted by the default implementation of [classfnc:webview]downloadCompletedEvent[/classfnc]().
309 */
310
311 KVSO_BEGIN_REGISTERCLASS(KvsObject_webView, "webview", "widget")
312
313 // page related
314 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, load)
315 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, setHtml)
316 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, frames)
317 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, makePreview)
318 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, appendWebViewActionToMenu)
319 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, setLinkDelegationPolicy)
320
321 // navigationn through the dom's tree
322 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, firstChild)
323 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, lastChild)
324 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, appendInside)
325 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, appendOutside)
326 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, parentElement)
327 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, nextSibling)
328
329 // find dom's elements
330 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, findAll)
331 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, findFirst)
332 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, findText)
333
334 // element info
335 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, elementTagName)
336 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, getDocumentElement)
337 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, elementAttributeNames)
338 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, setElementAttribute)
339 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, elementAttribute)
340 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, hitTestContent)
341 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, toPlainText)
342 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, setPlainText)
343 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, removeFromDocument)
344 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, removeClass)
345 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, addClass)
346
347 // css
348 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, setStyleProperty)
349 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, styleProperty)
350 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, setWebSetting)
351
352 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, classes)
353
354 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, setEventFilter)
355
356 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, addToJavaScriptWindowObject)
357 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, evaluateJavaScript)
358
359 // events
360 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, jsChangeEvent)
361 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, jsSubmitEvent)
362 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, jsClickEvent)
363 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, jsMouseOverEvent)
364 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, jsMouseOutEvent)
365 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, linkClickedEvent)
366 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, loadFinishedEvent)
367 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, loadProgressEvent)
368 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, loadStartedEvent)
369 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, downloadCompletedEvent)
370 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, downloadRequestEvent)
371 KVSO_REGISTER_HANDLER_BY_NAME(KvsObject_webView, downloadProgressEvent)
372
373 KVSO_END_REGISTERCLASS(KvsObject_webView)
374
375 KVSO_BEGIN_CONSTRUCTOR(KvsObject_webView, KviKvsObject)
376
377 KVSO_END_CONSTRUCTOR(KvsObject_webView)
378
379 KVSO_BEGIN_DESTRUCTOR(KvsObject_webView)
380
381 m_elementMapper.clear();
KVSO_END_CONSTRUCTOR(KvsObject_webView)382 KVSO_END_CONSTRUCTOR(KvsObject_webView)
383
384 bool KvsObject_webView::init(KviKvsRunTimeContext * c, KviKvsVariantList *)
385 {
386 //SET_OBJECT(KviKvsWebview);
387 setObject(new KviKvsWebView(parentScriptWidget(), getName().toUtf8().data(), this), true);
388 elementMapId = 1;
389 m_pContext = c;
390 m_pNetworkManager = new QNetworkAccessManager(this);
391 QWebPage * pPage = ((QWebView *)widget())->page();
392 connect(((QWebView *)widget()), SIGNAL(loadStarted()), this, SLOT(slotLoadStarted()));
393 connect(((QWebView *)widget()), SIGNAL(loadFinished(bool)), this, SLOT(slotLoadFinished(bool)));
394 connect(((QWebView *)widget()), SIGNAL(loadProgress(int)), this, SLOT(slotLoadProgress(int)));
395 connect(pPage, SIGNAL(linkClicked(const QUrl &)), this, SLOT(slotLinkClicked(const QUrl &)));
396 connect(pPage, SIGNAL(downloadRequested(const QNetworkRequest &)), this, SLOT(slotDownloadRequest(const QNetworkRequest &)));
397 return true;
398 }
insertElement(const QWebElement & ele)399 int KvsObject_webView::insertElement(const QWebElement & ele)
400 {
401 int eleid = getElementId(ele);
402 if(!eleid)
403 {
404 m_elementMapper[elementMapId] = ele;
405 return elementMapId++;
406 }
407 else
408 return eleid;
409 }
getElementId(const QWebElement & ele)410 int KvsObject_webView::getElementId(const QWebElement & ele)
411 {
412 QHashIterator<int, QWebElement> it(m_elementMapper);
413 while(it.hasNext())
414 {
415 it.next();
416 if(it.value() == ele)
417 return it.key();
418 }
419 return 0;
420 }
421
getElement(int iIdx)422 QWebElement KvsObject_webView::getElement(int iIdx)
423 {
424 return m_elementMapper.value(iIdx);
425 }
getFrames(QWebFrame * pCurFrame,QStringList & szFramesNames)426 void KvsObject_webView::getFrames(QWebFrame * pCurFrame, QStringList & szFramesNames)
427 {
428 szFramesNames.append(pCurFrame->title());
429 QList<QWebFrame *> lFrames = pCurFrame->childFrames();
430 for(int i = 0; i < lFrames.count(); i++)
431 {
432 QWebFrame * pChildFrame = lFrames.at(i);
433 if(pChildFrame->childFrames().count())
434 getFrames(pChildFrame, szFramesNames);
435 }
436 }
findFrame(QWebFrame * pCurFrame,QString & szFrameName)437 QWebFrame * KvsObject_webView::findFrame(QWebFrame * pCurFrame, QString & szFrameName)
438 {
439 if(pCurFrame->title() == szFrameName)
440 return pCurFrame;
441 QList<QWebFrame *> lFrames = pCurFrame->childFrames();
442 for(int i = 0; i < lFrames.count(); i++)
443 {
444 QWebFrame * pChildFrame = lFrames.at(i);
445 if(pChildFrame->childFrames().count())
446 {
447 pCurFrame = findFrame(pChildFrame, szFrameName);
448 if(pCurFrame)
449 return pCurFrame;
450 }
451 }
452 return nullptr;
453 }
454
KVSO_CLASS_FUNCTION(webView,setLinkDelegationPolicy)455 KVSO_CLASS_FUNCTION(webView, setLinkDelegationPolicy)
456 {
457 CHECK_INTERNAL_POINTER(widget())
458 QString szPolicy;
459 KVSO_PARAMETERS_BEGIN(c)
460 KVSO_PARAMETER("policy", KVS_PT_STRING, 0, szPolicy)
461 KVSO_PARAMETERS_END(c)
462 QWebPage::LinkDelegationPolicy policy = QWebPage::DontDelegateLinks;
463 if(KviQString::equalCI(szPolicy, "DontDelegateLinks"))
464 policy = QWebPage::DontDelegateLinks;
465 else if(KviQString::equalCI(szPolicy, "DelegateExternalLinks"))
466 policy = QWebPage::DelegateExternalLinks;
467 else if(KviQString::equalCI(szPolicy, "DelegateAllLinks"))
468 policy = QWebPage::DelegateAllLinks;
469 else
470 c->warning(__tr2qs_ctx("Unknown delegation policy '%Q'- Switch do default dontDelegateLinks", "objects"), &szPolicy);
471 ((QWebView *)widget())->page()->setLinkDelegationPolicy(policy);
472 return true;
473 }
474
KVSO_CLASS_FUNCTION(webView,load)475 KVSO_CLASS_FUNCTION(webView, load)
476 {
477 CHECK_INTERNAL_POINTER(widget())
478 QString szUrl;
479 KVSO_PARAMETERS_BEGIN(c)
480 KVSO_PARAMETER("url", KVS_PT_STRING, 0, szUrl)
481 KVSO_PARAMETERS_END(c)
482 ((QWebView *)widget())->load(QUrl(szUrl));
483 return true;
484 }
KVSO_CLASS_FUNCTION(webView,setHtml)485 KVSO_CLASS_FUNCTION(webView, setHtml)
486 {
487 CHECK_INTERNAL_POINTER(widget())
488 QString szHtml, szUrlBase;
489 KVSO_PARAMETERS_BEGIN(c)
490 KVSO_PARAMETER("szHtml", KVS_PT_STRING, 0, szHtml)
491 KVSO_PARAMETER("urlbase", KVS_PT_STRING, KVS_PF_OPTIONAL, szUrlBase)
492 KVSO_PARAMETERS_END(c)
493 ((QWebView *)widget())->setHtml(szHtml, QUrl(szUrlBase));
494 return true;
495 }
KVSO_CLASS_FUNCTION(webView,makePreview)496 KVSO_CLASS_FUNCTION(webView, makePreview)
497 {
498 CHECK_INTERNAL_POINTER(widget())
499 QSize size = ((QWebView *)widget())->page()->mainFrame()->contentsSize();
500 QImage * pImage = new QImage(212, 142, QImage::Format_RGB32);
501 QWebFrame * pFrame = ((QWebView *)widget())->page()->mainFrame();
502 QPainter painter(pImage);
503 painter.setRenderHint(QPainter::Antialiasing, true);
504 painter.setRenderHint(QPainter::TextAntialiasing, true);
505 painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
506 double dWScale = size.width() > 0 ? (212.0 / (double)(size.width())) : 0;
507 double dHScale = dWScale;
508 if((size.height() * dWScale) < 142)
509 {
510 // solution 1 is to fill the missing bacgkround
511 painter.fillRect(0, 0, 212, 142, QColor(255, 255, 255));
512 // solution 2 is to stretch the contents, but this doesn't work well because
513 // the frame reports a size that doesn't exactly match the document
514 //dHScale = 142.0 / (double)(size.height());
515 }
516 painter.scale(dWScale, dHScale);
517 pFrame->documentElement().render(&painter);
518 painter.end();
519 KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass("pixmap");
520 KviKvsVariantList params;
521 KviKvsObject * pObject = pClass->allocateInstance(nullptr, "internalpixmap", c->context(), ¶ms);
522 ((KvsObject_pixmap *)pObject)->setInternalImage(pImage);
523 c->returnValue()->setHObject(pObject->handle());
524 return true;
525 }
526
KVSO_CLASS_FUNCTION(webView,findAll)527 KVSO_CLASS_FUNCTION(webView, findAll)
528 {
529 CHECK_INTERNAL_POINTER(widget())
530 QString szQuery;
531 KviKvsArray * pArray;
532 kvs_int_t iEleId;
533 KVSO_PARAMETERS_BEGIN(c)
534 KVSO_PARAMETER("element_identifier", KVS_PT_INTEGER, 0, iEleId)
535 KVSO_PARAMETER("query", KVS_PT_STRING, 0, szQuery)
536 KVSO_PARAMETERS_END(c)
537 QWebElement element = getElement(iEleId);
538 if(element.isNull())
539 {
540 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
541 return true;
542 }
543 QWebElementCollection elementCollection = element.findAll(szQuery);
544 if(!elementCollection.count())
545 return true;
546 //qDebug("collection %i",elementCollection.count());
547 int idx = 0;
548 pArray = new KviKvsArray();
549 for(int i = 0; i < elementCollection.count(); i++)
550 {
551 QWebElement element = elementCollection.at(i);
552 int id = insertElement(element);
553 pArray->set(idx, new KviKvsVariant((kvs_int_t)id));
554 idx++;
555 }
556 c->returnValue()->setArray(pArray);
557 return true;
558 }
559
KVSO_CLASS_FUNCTION(webView,evaluateJavaScript)560 KVSO_CLASS_FUNCTION(webView, evaluateJavaScript)
561 {
562 CHECK_INTERNAL_POINTER(widget())
563 QString szScript;
564 kvs_int_t iEleId;
565 KVSO_PARAMETERS_BEGIN(c)
566 KVSO_PARAMETER("element_identifier", KVS_PT_INTEGER, 0, iEleId)
567 KVSO_PARAMETER("script_code", KVS_PT_STRING, 0, szScript)
568 KVSO_PARAMETERS_END(c)
569 QWebElement element = getElement(iEleId);
570 if(element.isNull())
571 {
572 c->warning(__tr2qs_ctx("Document element is null: you must call getDocumentElement first", "objects"));
573 return true;
574 }
575 QVariant vRes = element.evaluateJavaScript(szScript);
576 if(vRes.type() == QVariant::String)
577 {
578 QString szVal = vRes.toString();
579 c->returnValue()->setString(szVal);
580 }
581 else
582 c->warning(__tr2qs_ctx("Unsupported datatype", "objects"));
583 return true;
584 }
585
KVSO_CLASS_FUNCTION(webView,findFirst)586 KVSO_CLASS_FUNCTION(webView, findFirst)
587 {
588 QString szQuery;
589 kvs_int_t iEleId;
590 KVSO_PARAMETERS_BEGIN(c)
591 KVSO_PARAMETER("element_identifier", KVS_PT_INTEGER, 0, iEleId)
592 KVSO_PARAMETER("query", KVS_PT_STRING, 0, szQuery)
593 KVSO_PARAMETERS_END(c)
594 QWebElement element = getElement(iEleId);
595 if(element.isNull())
596 {
597 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
598 return true;
599 }
600 QWebElement tempElement = element.findFirst(szQuery);
601 if(tempElement.isNull())
602 {
603 c->returnValue()->setInteger(-1);
604 return true;
605 }
606 int id = insertElement(tempElement);
607 c->returnValue()->setInteger((kvs_int_t)id);
608 return true;
609 }
610
KVSO_CLASS_FUNCTION(webView,removeFromDocument)611 KVSO_CLASS_FUNCTION(webView, removeFromDocument)
612 {
613 kvs_int_t iEleId;
614 KVSO_PARAMETERS_BEGIN(c)
615 KVSO_PARAMETER("element_identifier", KVS_PT_INTEGER, 0, iEleId)
616 KVSO_PARAMETERS_END(c)
617 QWebElement element = getElement(iEleId);
618 if(element.isNull())
619 {
620 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
621 return true;
622 }
623 element.removeFromDocument();
624 return true;
625 }
626
KVSO_CLASS_FUNCTION(webView,appendInside)627 KVSO_CLASS_FUNCTION(webView, appendInside)
628 {
629 kvs_int_t iEleId;
630 QString szCode;
631 KVSO_PARAMETERS_BEGIN(c)
632 KVSO_PARAMETER("element_identifier", KVS_PT_INTEGER, 0, iEleId)
633 KVSO_PARAMETER("name", KVS_PT_NONEMPTYSTRING, 0, szCode)
634 KVSO_PARAMETERS_END(c)
635 QWebElement element = getElement(iEleId);
636 if(element.isNull())
637 {
638 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
639 return true;
640 }
641 element.appendInside(szCode);
642 return true;
643 }
644
KVSO_CLASS_FUNCTION(webView,appendOutside)645 KVSO_CLASS_FUNCTION(webView, appendOutside)
646 {
647 kvs_int_t iEleId;
648 QString szCode;
649 KVSO_PARAMETERS_BEGIN(c)
650 KVSO_PARAMETER("element_identifier", KVS_PT_INTEGER, 0, iEleId)
651 KVSO_PARAMETER("name", KVS_PT_NONEMPTYSTRING, 0, szCode)
652 KVSO_PARAMETERS_END(c)
653 QWebElement element = getElement(iEleId);
654 if(element.isNull())
655 {
656 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
657 return true;
658 }
659 element.appendOutside(szCode);
660 return true;
661 }
KVSO_CLASS_FUNCTION(webView,nextSibling)662 KVSO_CLASS_FUNCTION(webView, nextSibling)
663 {
664 CHECK_INTERNAL_POINTER(widget())
665 kvs_int_t iEleId;
666 KVSO_PARAMETERS_BEGIN(c)
667 KVSO_PARAMETER("element_identifier", KVS_PT_INTEGER, 0, iEleId)
668 KVSO_PARAMETERS_END(c)
669 QWebElement element = getElement(iEleId);
670 if(element.isNull())
671 {
672 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
673 return true;
674 }
675 QWebElement tempElement = element.nextSibling();
676 if(tempElement.isNull())
677 {
678 c->returnValue()->setInteger(-1);
679 return true;
680 }
681 int id = insertElement(tempElement);
682 c->returnValue()->setInteger((kvs_int_t)id);
683 return true;
684 }
685
KVSO_CLASS_FUNCTION(webView,frames)686 KVSO_CLASS_FUNCTION(webView, frames)
687 {
688 CHECK_INTERNAL_POINTER(widget())
689 QWebFrame * pFrame = ((QWebView *)widget())->page()->mainFrame();
690 QStringList szFramesNames;
691 getFrames(pFrame, szFramesNames);
692 KviKvsArray * pArray = new KviKvsArray();
693 c->returnValue()->setArray(pArray);
694 return true;
695 }
696
KVSO_CLASS_FUNCTION(webView,elementTagName)697 KVSO_CLASS_FUNCTION(webView, elementTagName)
698 {
699 CHECK_INTERNAL_POINTER(widget())
700 kvs_int_t iEleId;
701 KVSO_PARAMETERS_BEGIN(c)
702 KVSO_PARAMETER("element_identifier", KVS_PT_INTEGER, 0, iEleId)
703 KVSO_PARAMETERS_END(c)
704 QWebElement element = getElement(iEleId);
705 if(element.isNull())
706 {
707 // qDebug("isnull ad index %i",iEleId);
708 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
709 return true;
710 }
711 c->returnValue()->setString(element.tagName());
712 return true;
713 }
714
KVSO_CLASS_FUNCTION(webView,setElementAttribute)715 KVSO_CLASS_FUNCTION(webView, setElementAttribute)
716 {
717 CHECK_INTERNAL_POINTER(widget())
718 QString szName, szValue;
719 kvs_int_t iEleId;
720 KVSO_PARAMETERS_BEGIN(c)
721 KVSO_PARAMETER("element_identifier", KVS_PT_INTEGER, 0, iEleId)
722 KVSO_PARAMETER("name", KVS_PT_NONEMPTYSTRING, 0, szName)
723 KVSO_PARAMETER("value", KVS_PT_STRING, 0, szValue)
724 KVSO_PARAMETERS_END(c)
725 QWebElement element = getElement(iEleId);
726 if(element.isNull())
727 {
728 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
729 return true;
730 }
731 element.setAttribute(szName, szValue);
732 return true;
733 }
734
KVSO_CLASS_FUNCTION(webView,removeClass)735 KVSO_CLASS_FUNCTION(webView, removeClass)
736 {
737 CHECK_INTERNAL_POINTER(widget())
738 QString szClassName;
739 kvs_int_t iEleId;
740 KVSO_PARAMETERS_BEGIN(c)
741 KVSO_PARAMETER("element_identifier", KVS_PT_INTEGER, 0, iEleId)
742 KVSO_PARAMETER("class_name", KVS_PT_NONEMPTYSTRING, 0, szClassName)
743 KVSO_PARAMETERS_END(c)
744 QWebElement element = getElement(iEleId);
745 if(element.isNull())
746 {
747 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
748 return true;
749 }
750 element.removeClass(szClassName);
751 return true;
752 }
KVSO_CLASS_FUNCTION(webView,addClass)753 KVSO_CLASS_FUNCTION(webView, addClass)
754 {
755 CHECK_INTERNAL_POINTER(widget())
756 QString szClassName;
757 kvs_int_t iEleId;
758 KVSO_PARAMETERS_BEGIN(c)
759 KVSO_PARAMETER("element_identifier", KVS_PT_INTEGER, 0, iEleId)
760 KVSO_PARAMETER("class_name", KVS_PT_NONEMPTYSTRING, 0, szClassName)
761 KVSO_PARAMETERS_END(c)
762 QWebElement element = getElement(iEleId);
763 if(element.isNull())
764 {
765 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
766 return true;
767 }
768 element.addClass(szClassName);
769 return true;
770 }
KVSO_CLASS_FUNCTION(webView,setWebSetting)771 KVSO_CLASS_FUNCTION(webView, setWebSetting)
772 {
773 CHECK_INTERNAL_POINTER(widget())
774 QString szName;
775 bool bEnabled;
776 KVSO_PARAMETERS_BEGIN(c)
777 KVSO_PARAMETER("name", KVS_PT_NONEMPTYSTRING, 0, szName)
778 KVSO_PARAMETER("value", KVS_PT_BOOLEAN, 0, bEnabled)
779 KVSO_PARAMETERS_END(c)
780 bool found = false;
781 unsigned int j = 0;
782 for(; j < webattributes_num; j++)
783 {
784 if(KviQString::equalCI(szName, webattributes_tbl[j]))
785 {
786 found = true;
787 break;
788 }
789 }
790 if(found)
791 ((QWebView *)widget())->settings()->setAttribute(webattributes_cod[j], bEnabled);
792 else
793 c->warning(__tr2qs_ctx("Unknown web setting '%Q'", "objects"), &szName);
794 return true;
795 }
KVSO_CLASS_FUNCTION(webView,findText)796 KVSO_CLASS_FUNCTION(webView, findText)
797 {
798 CHECK_INTERNAL_POINTER(widget())
799 QString szName;
800 QStringList szFindFlag;
801 KVSO_PARAMETERS_BEGIN(c)
802 KVSO_PARAMETER("find_text", KVS_PT_NONEMPTYSTRING, 0, szName)
803 KVSO_PARAMETER("find_flag", KVS_PT_STRINGLIST, KVS_PF_OPTIONAL, szFindFlag)
804 KVSO_PARAMETERS_END(c)
805 int findflag = 0;
806 int sum = 0;
807 for(auto & it : szFindFlag)
808 {
809 findflag = 0;
810 for(unsigned int j = 0; j < findflag_num; j++)
811 {
812 if(KviQString::equalCI(it, findflag_tbl[j]))
813 {
814 findflag = findflag_cod[j];
815 break;
816 }
817 }
818 if(findflag)
819 sum = sum | findflag;
820 else
821 c->warning(__tr2qs_ctx("Unknown findflag '%Q'", "objects"), &it);
822 }
823 ((QWebView *)widget())->findText(szName, (QWebPage::FindFlags)findflag);
824 return true;
825 }
KVSO_CLASS_FUNCTION(webView,elementAttribute)826 KVSO_CLASS_FUNCTION(webView, elementAttribute)
827 {
828 CHECK_INTERNAL_POINTER(widget())
829 QString szName;
830 kvs_int_t iEleId;
831 KVSO_PARAMETERS_BEGIN(c)
832 KVSO_PARAMETER("element_identifier", KVS_PT_INTEGER, 0, iEleId)
833 KVSO_PARAMETER("name", KVS_PT_NONEMPTYSTRING, 0, szName)
834 KVSO_PARAMETERS_END(c)
835 QWebElement element = getElement(iEleId);
836 if(element.isNull())
837 {
838 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
839 return true;
840 }
841
842 // workaround for this issue: https://bugreports.qt.nokia.com//browse/QTWEBKIT-88
843 if(KviQString::equalCI(element.tagName(), "input"))
844 {
845 QVariant value = element.evaluateJavaScript("this." + szName);
846 c->returnValue()->setString(value.toString());
847 return true;
848 }
849 c->returnValue()->setString(element.attribute(szName));
850 return true;
851 }
852
KVSO_CLASS_FUNCTION(webView,elementAttributeNames)853 KVSO_CLASS_FUNCTION(webView, elementAttributeNames)
854 {
855 CHECK_INTERNAL_POINTER(widget())
856 kvs_int_t iEleId;
857 KVSO_PARAMETERS_BEGIN(c)
858 KVSO_PARAMETER("identifier", KVS_PT_INTEGER, 0, iEleId)
859 KVSO_PARAMETERS_END(c)
860 QString szAttributeNames;
861 QWebElement element = getElement(iEleId);
862 if(element.isNull())
863 {
864 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
865 return true;
866 }
867 szAttributeNames = element.attributeNames().join(",");
868 c->returnValue()->setString(szAttributeNames);
869 return true;
870 }
KVSO_CLASS_FUNCTION(webView,classes)871 KVSO_CLASS_FUNCTION(webView, classes)
872 {
873 CHECK_INTERNAL_POINTER(widget())
874 kvs_int_t iEleId;
875 KVSO_PARAMETERS_BEGIN(c)
876 KVSO_PARAMETER("identifier", KVS_PT_INTEGER, 0, iEleId)
877 KVSO_PARAMETERS_END(c)
878 QWebElement element = getElement(iEleId);
879 if(element.isNull())
880 {
881 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
882 return true;
883 }
884 QString szClasses;
885 szClasses = element.classes().join(",");
886 c->returnValue()->setString(szClasses);
887 return true;
888 }
889
KVSO_CLASS_FUNCTION(webView,toPlainText)890 KVSO_CLASS_FUNCTION(webView, toPlainText)
891 {
892 CHECK_INTERNAL_POINTER(widget())
893 kvs_int_t iEleId;
894 KVSO_PARAMETERS_BEGIN(c)
895 KVSO_PARAMETER("identifier", KVS_PT_INTEGER, 0, iEleId)
896 KVSO_PARAMETERS_END(c)
897 QWebElement element = getElement(iEleId);
898 if(element.isNull())
899 {
900 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
901 return true;
902 }
903 c->returnValue()->setString(element.toPlainText());
904 return true;
905 }
KVSO_CLASS_FUNCTION(webView,setPlainText)906 KVSO_CLASS_FUNCTION(webView, setPlainText)
907 {
908 CHECK_INTERNAL_POINTER(widget())
909 QString szText;
910 kvs_int_t iEleId;
911 KVSO_PARAMETERS_BEGIN(c)
912 KVSO_PARAMETER("identifier", KVS_PT_INTEGER, 0, iEleId)
913 KVSO_PARAMETER("plaintext", KVS_PT_STRING, 0, szText)
914 KVSO_PARAMETERS_END(c)
915 QWebElement element = getElement(iEleId);
916 if(element.isNull())
917 {
918 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
919 return true;
920 }
921 element.setPlainText(szText);
922 return true;
923 }
924
KVSO_CLASS_FUNCTION(webView,firstChild)925 KVSO_CLASS_FUNCTION(webView, firstChild)
926 {
927 CHECK_INTERNAL_POINTER(widget())
928 kvs_int_t iEleId;
929 KVSO_PARAMETERS_BEGIN(c)
930 KVSO_PARAMETER("identifier", KVS_PT_INTEGER, 0, iEleId)
931 KVSO_PARAMETERS_END(c)
932 QWebElement element = getElement(iEleId);
933 if(element.isNull())
934 {
935 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
936 return true;
937 }
938
939 QWebElement tempElement = element.firstChild();
940 if(tempElement.isNull())
941 {
942 c->returnValue()->setInteger(-1);
943 return true;
944 }
945 int id = insertElement(tempElement);
946 c->returnValue()->setInteger((kvs_int_t)id);
947 return true;
948 }
KVSO_CLASS_FUNCTION(webView,lastChild)949 KVSO_CLASS_FUNCTION(webView, lastChild)
950 {
951 CHECK_INTERNAL_POINTER(widget())
952 kvs_int_t iEleId;
953 KVSO_PARAMETERS_BEGIN(c)
954 KVSO_PARAMETER("identifier", KVS_PT_INTEGER, 0, iEleId)
955 KVSO_PARAMETERS_END(c)
956 QWebElement element = getElement(iEleId);
957 if(element.isNull())
958 {
959 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
960 return true;
961 }
962
963 QWebElement tempElement = element.lastChild();
964 if(tempElement.isNull())
965 {
966 c->returnValue()->setInteger(-1);
967 return true;
968 }
969 int id = insertElement(tempElement);
970 c->returnValue()->setInteger((kvs_int_t)id);
971 return true;
972 }
KVSO_CLASS_FUNCTION(webView,parentElement)973 KVSO_CLASS_FUNCTION(webView, parentElement)
974 {
975 CHECK_INTERNAL_POINTER(widget())
976 kvs_int_t iEleId;
977 KVSO_PARAMETERS_BEGIN(c)
978 KVSO_PARAMETER("identifier", KVS_PT_INTEGER, 0, iEleId)
979 KVSO_PARAMETERS_END(c)
980 QWebElement element = getElement(iEleId);
981 if(element.isNull())
982 {
983 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
984 return true;
985 }
986
987 QWebElement tempElement = element.parent();
988 if(tempElement.isNull())
989 {
990 c->returnValue()->setInteger(-1);
991 return true;
992 }
993 int id = insertElement(tempElement);
994 c->returnValue()->setInteger((kvs_int_t)id);
995 return true;
996 }
997
KVSO_CLASS_FUNCTION(webView,styleProperty)998 KVSO_CLASS_FUNCTION(webView, styleProperty)
999 {
1000 CHECK_INTERNAL_POINTER(widget())
1001 QString szName, szStyleResolveStrategy;
1002 kvs_int_t iEleId;
1003 KVSO_PARAMETERS_BEGIN(c)
1004 KVSO_PARAMETER("identifier", KVS_PT_INTEGER, 0, iEleId)
1005 KVSO_PARAMETER("name", KVS_PT_NONEMPTYSTRING, 0, szName)
1006 KVSO_PARAMETER("style_resolve_strategy", KVS_PT_STRING, KVS_PF_OPTIONAL, szStyleResolveStrategy)
1007 KVSO_PARAMETERS_END(c)
1008 QWebElement element = getElement(iEleId);
1009 if(element.isNull())
1010 {
1011 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
1012 return true;
1013 }
1014 QWebElement::StyleResolveStrategy styleStrategy = QWebElement::CascadedStyle;
1015 if(!szStyleResolveStrategy.isEmpty())
1016 {
1017 if(KviQString::equalCI(szStyleResolveStrategy, "InlineStyle"))
1018 styleStrategy = QWebElement::InlineStyle;
1019 else if(KviQString::equalCI(szStyleResolveStrategy, "CascadedStyle"))
1020 styleStrategy = QWebElement::CascadedStyle;
1021 else if(KviQString::equalCI(szStyleResolveStrategy, "ComputedStyle"))
1022 styleStrategy = QWebElement::ComputedStyle;
1023 else
1024 {
1025 c->warning(__tr2qs_ctx("Unknown styleResolveStrategy: '%Q' - Switching to default CascadedStyle strategy", "objects"), &szStyleResolveStrategy);
1026 }
1027 }
1028 c->returnValue()->setString(element.styleProperty(szName, styleStrategy));
1029 return true;
1030 }
KVSO_CLASS_FUNCTION(webView,setStyleProperty)1031 KVSO_CLASS_FUNCTION(webView, setStyleProperty)
1032 {
1033 CHECK_INTERNAL_POINTER(widget())
1034 QString szProperty, szValue;
1035 kvs_int_t iEleId;
1036 KVSO_PARAMETERS_BEGIN(c)
1037 KVSO_PARAMETER("identifier", KVS_PT_INTEGER, 0, iEleId)
1038 KVSO_PARAMETER("property", KVS_PT_STRING, 0, szProperty)
1039 KVSO_PARAMETER("value", KVS_PT_STRING, 0, szValue)
1040 KVSO_PARAMETERS_END(c)
1041 QWebElement element = getElement(iEleId);
1042 if(element.isNull())
1043 {
1044 c->warning(__tr2qs_ctx("Document element with ID %d doesn't exist", "objects"), iEleId);
1045 return true;
1046 }
1047 element.setStyleProperty(szProperty, szValue);
1048 return true;
1049 }
1050
KVSO_CLASS_FUNCTION(webView,getDocumentElement)1051 KVSO_CLASS_FUNCTION(webView, getDocumentElement)
1052 {
1053 CHECK_INTERNAL_POINTER(widget())
1054 QString szFrameName;
1055 KVSO_PARAMETERS_BEGIN(c)
1056 KVSO_PARAMETER("frame_name", KVS_PT_STRING, KVS_PF_OPTIONAL, szFrameName)
1057 KVSO_PARAMETERS_END(c)
1058 QWebFrame * pFrame;
1059 pFrame = ((QWebView *)widget())->page()->mainFrame();
1060 if(!szFrameName.isEmpty())
1061 {
1062 pFrame = findFrame(pFrame, szFrameName);
1063 if(!pFrame)
1064 {
1065 c->warning(__tr2qs_ctx("Unknown frame '%Q'", "objects"), &szFrameName);
1066 return true;
1067 }
1068 }
1069 int id = insertElement(pFrame->documentElement());
1070 c->returnValue()->setInteger((kvs_int_t)id);
1071 return true;
1072 }
KVSO_CLASS_FUNCTION(webView,addToJavaScriptWindowObject)1073 KVSO_CLASS_FUNCTION(webView, addToJavaScriptWindowObject)
1074 {
1075 CHECK_INTERNAL_POINTER(widget())
1076 QString szFrameName, szObjectName;
1077 KVSO_PARAMETERS_BEGIN(c)
1078 KVSO_PARAMETER("object_name", KVS_PT_NONEMPTYSTRING, 0, szObjectName)
1079 KVSO_PARAMETER("frame_name", KVS_PT_STRING, KVS_PF_OPTIONAL, szFrameName)
1080 KVSO_PARAMETERS_END(c)
1081 QWebFrame * pFrame;
1082 pFrame = ((QWebView *)widget())->page()->mainFrame();
1083 if(!szFrameName.isEmpty())
1084 {
1085 pFrame = findFrame(pFrame, szFrameName);
1086 if(!pFrame)
1087 {
1088 c->warning(__tr2qs_ctx("Unknown frame '%Q'", "objects"), &szFrameName);
1089 return true;
1090 }
1091 }
1092 pFrame->addToJavaScriptWindowObject(szObjectName, this);
1093 return true;
1094 }
KVSO_CLASS_FUNCTION(webView,setEventFilter)1095 KVSO_CLASS_FUNCTION(webView, setEventFilter)
1096 {
1097 QWebFrame * pFrame;
1098 pFrame = ((QWebView *)widget())->page()->mainFrame();
1099 pFrame->addToJavaScriptWindowObject("kvs", this);
1100 return true;
1101 }
1102
KVSO_CLASS_FUNCTION(webView,hitTestContent)1103 KVSO_CLASS_FUNCTION(webView, hitTestContent)
1104 {
1105 CHECK_INTERNAL_POINTER(widget())
1106 kvs_int_t iYPos, iXPos;
1107 KVSO_PARAMETERS_BEGIN(c)
1108 KVSO_PARAMETER("x_pos", KVS_PT_INT, 0, iXPos)
1109 KVSO_PARAMETER("y_pos", KVS_PT_INT, 0, iYPos)
1110 KVSO_PARAMETERS_END(c)
1111 QWebFrame * pFrame;
1112 pFrame = ((QWebView *)widget())->page()->mainFrame();
1113 QWebHitTestResult res = pFrame->hitTestContent(QPoint(iXPos, iYPos));
1114 if(res.isNull())
1115 return true;
1116 KviKvsHash * pHash = new KviKvsHash();
1117 pHash->set("imageurl", new KviKvsVariant(res.imageUrl().toString()));
1118 pHash->set("linktitle", new KviKvsVariant(res.linkTitle().toString()));
1119 pHash->set("linktext", new KviKvsVariant(res.linkText()));
1120 pHash->set("linkelement", new KviKvsVariant((kvs_int_t)insertElement(res.linkElement())));
1121 pHash->set("enclosingelement", new KviKvsVariant((kvs_int_t)insertElement(res.enclosingBlockElement())));
1122 pHash->set("element", new KviKvsVariant((kvs_int_t)insertElement(res.element())));
1123 c->returnValue()->setHash(pHash);
1124 return true;
1125 }
1126
KVSO_CLASS_FUNCTION(webView,appendWebViewActionToMenu)1127 KVSO_CLASS_FUNCTION(webView, appendWebViewActionToMenu)
1128 {
1129 CHECK_INTERNAL_POINTER(widget())
1130 KviKvsObject * ob;
1131 kvs_hobject_t hObject;
1132 QString szActionName, szIcon;
1133 KVSO_PARAMETERS_BEGIN(c)
1134 KVSO_PARAMETER("popup", KVS_PT_HOBJECT, 0, hObject)
1135 KVSO_PARAMETER("action_name", KVS_PT_NONEMPTYSTRING, 0, szActionName)
1136 KVSO_PARAMETER("icon", KVS_PT_STRING, KVS_PF_OPTIONAL, szIcon)
1137 KVSO_PARAMETERS_END(c)
1138 ob = KviKvsKernel::instance()->objectController()->lookupObject(hObject);
1139 if(!ob)
1140 {
1141 c->warning(__tr2qs_ctx("Widget parameter is not an object", "objects"));
1142 return true;
1143 }
1144 if(!ob->object())
1145 {
1146 c->warning(__tr2qs_ctx("Widget parameter is not a valid object", "objects"));
1147 return true;
1148 }
1149 if(!ob->inheritsClass("popupmenu"))
1150 {
1151 c->warning(__tr2qs_ctx("Can't add a non-popupmenu object", "objects"));
1152 return true;
1153 }
1154 QAction * pAction = nullptr;
1155 for(unsigned int i = 0; i < actions_num; i++)
1156 {
1157 if(KviQString::equalCI(szActionName, actions_tbl[i]))
1158 {
1159 pAction = ((QWebView *)widget())->pageAction(actions_cod[i]);
1160 break;
1161 }
1162 }
1163 if(!pAction)
1164 {
1165 c->warning(__tr2qs_ctx("Unknown action '%Q':", "objects"), &szActionName);
1166 return true;
1167 }
1168 if(!szIcon.isEmpty())
1169 {
1170 QPixmap * pix;
1171 pix = g_pIconManager->getImage(szIcon);
1172 if(pix)
1173 pAction->setIcon(*pix);
1174 else
1175 c->warning(__tr2qs_ctx("Icon '%Q' doesn't exist", "objects"), &szIcon);
1176 }
1177 ((QMenu *)(ob->object()))->addAction(pAction);
1178 return true;
1179 }
1180
KVSO_CLASS_FUNCTION(webView,loadFinishedEvent)1181 KVSO_CLASS_FUNCTION(webView, loadFinishedEvent)
1182 {
1183 emitSignal("loadFinished", c, c->params());
1184 return true;
1185 }
1186
KVSO_CLASS_FUNCTION(webView,loadProgressEvent)1187 KVSO_CLASS_FUNCTION(webView, loadProgressEvent)
1188 {
1189 emitSignal("loadProgress", c, c->params());
1190 return true;
1191 }
1192
KVSO_CLASS_FUNCTION(webView,loadStartedEvent)1193 KVSO_CLASS_FUNCTION(webView, loadStartedEvent)
1194 {
1195 emitSignal("loadStarted", c);
1196 return true;
1197 }
1198
KVSO_CLASS_FUNCTION(webView,downloadCompletedEvent)1199 KVSO_CLASS_FUNCTION(webView, downloadCompletedEvent)
1200 {
1201 emitSignal("downloadCompleted", c, c->params());
1202 return true;
1203 }
1204
KVSO_CLASS_FUNCTION(webView,downloadProgressEvent)1205 KVSO_CLASS_FUNCTION(webView, downloadProgressEvent)
1206 {
1207 emitSignal("downloadProgress", c, c->params());
1208 return true;
1209 }
1210
KVSO_CLASS_FUNCTION(webView,linkClickedEvent)1211 KVSO_CLASS_FUNCTION(webView, linkClickedEvent)
1212 {
1213 emitSignal("linkClicked", c, c->params());
1214 return true;
1215 }
1216
KVSO_CLASS_FUNCTION(webView,downloadRequestEvent)1217 KVSO_CLASS_FUNCTION(webView, downloadRequestEvent)
1218 {
1219 emitSignal("downloadRequest", c, c->params());
1220 return true;
1221 }
1222
KVSO_CLASS_FUNCTION(webView,jsSubmitEvent)1223 KVSO_CLASS_FUNCTION(webView, jsSubmitEvent)
1224 {
1225 emitSignal("jssubmit", c, c->params());
1226 return true;
1227 }
KVSO_CLASS_FUNCTION(webView,jsChangeEvent)1228 KVSO_CLASS_FUNCTION(webView, jsChangeEvent)
1229 {
1230 emitSignal("jschange", c, c->params());
1231 return true;
1232 }
KVSO_CLASS_FUNCTION(webView,jsClickEvent)1233 KVSO_CLASS_FUNCTION(webView, jsClickEvent)
1234 {
1235 emitSignal("jsclick", c, c->params());
1236 return true;
1237 }
KVSO_CLASS_FUNCTION(webView,jsMouseOverEvent)1238 KVSO_CLASS_FUNCTION(webView, jsMouseOverEvent)
1239 {
1240 emitSignal("jsmouseover", c, c->params());
1241 return true;
1242 }
KVSO_CLASS_FUNCTION(webView,jsMouseOutEvent)1243 KVSO_CLASS_FUNCTION(webView, jsMouseOutEvent)
1244 {
1245 emitSignal("jsmouseout", c, c->params());
1246 return true;
1247 }
slotOnChange(QString szParam)1248 void KvsObject_webView::slotOnChange(QString szParam)
1249 {
1250 //qDebug("change");
1251 KviKvsVariantList params(new KviKvsVariant(szParam));
1252 callFunction(this, "jsChangeEvent", ¶ms);
1253 }
1254
slotOnSubmit(QString szParam)1255 void KvsObject_webView::slotOnSubmit(QString szParam)
1256 {
1257 // ,QString szParam2,QString szParam3
1258 //qDebug("slotonsubmit");
1259 KviKvsVariantList params(new KviKvsVariant(szParam));
1260 callFunction(this, "jsSubmitEvent", ¶ms);
1261 }
1262
slotOnClick(QString szParam)1263 void KvsObject_webView::slotOnClick(QString szParam)
1264 {
1265 KviKvsVariantList params(new KviKvsVariant(szParam));
1266 callFunction(this, "jsClickEvent", ¶ms);
1267 }
slotOnMouseOver(QString szParam)1268 void KvsObject_webView::slotOnMouseOver(QString szParam)
1269 {
1270 KviKvsVariantList params(new KviKvsVariant(szParam));
1271 callFunction(this, "jsMouseOverEvent", ¶ms);
1272 }
slotOnMouseOut(QString szParam)1273 void KvsObject_webView::slotOnMouseOut(QString szParam)
1274 {
1275 KviKvsVariantList params(new KviKvsVariant(szParam));
1276 callFunction(this, "jsMouseOutEvent", ¶ms);
1277 }
1278
1279 // slots
slotLoadFinished(bool bOk)1280 void KvsObject_webView::slotLoadFinished(bool bOk)
1281 {
1282 if(bOk)
1283 m_currentElement = ((QWebView *)widget())->page()->mainFrame()->documentElement();
1284 KviKvsVariantList params(new KviKvsVariant(bOk));
1285 callFunction(this, "loadFinishedEvent", ¶ms);
1286 }
1287
slotLoadStarted()1288 void KvsObject_webView::slotLoadStarted()
1289 {
1290 KviKvsVariantList * lParams = nullptr;
1291 callFunction(this, "loadStartedEvent", lParams);
1292 }
1293
slotLoadProgress(int iProgress)1294 void KvsObject_webView::slotLoadProgress(int iProgress)
1295 {
1296 KviKvsVariantList params(new KviKvsVariant((kvs_int_t)iProgress));
1297 callFunction(this, "loadProgressEvent", ¶ms);
1298 }
1299
slotLinkClicked(const QUrl & url)1300 void KvsObject_webView::slotLinkClicked(const QUrl & url)
1301 {
1302 QString szUrl = url.toString();
1303 KviKvsVariantList params(new KviKvsVariant(szUrl));
1304 callFunction(this, "linkClickedEvent", ¶ms);
1305 }
1306
slotDownloadRequest(const QNetworkRequest & r)1307 void KvsObject_webView::slotDownloadRequest(const QNetworkRequest & r)
1308 {
1309 QNetworkReply * pReply = m_pNetworkManager->get(r);
1310 QString szFilePath = "";
1311 KviKvsVariant * filepathret = new KviKvsVariant(szFilePath);
1312 KviKvsVariantList params(new KviKvsVariant(r.url().toString()));
1313 callFunction(this, "downloadRequestEvent", filepathret, ¶ms);
1314 filepathret->asString(szFilePath);
1315 if(!szFilePath.isEmpty())
1316 {
1317 QFile * pFile = new QFile(szFilePath);
1318 if(!pFile->open(QIODevice::WriteOnly))
1319 {
1320 m_pContext->warning(__tr2qs_ctx("Invalid file path '%Q'", "objects"), &szFilePath);
1321 pReply->abort();
1322 pReply->deleteLater();
1323 return;
1324 }
1325 (void)new KviKvsDownloadHandler(this, pFile, pReply, g_iDownloadId);
1326 g_iDownloadId++;
1327 }
1328 }
1329
KviKvsWebView(QWidget * par,const char * name,KvsObject_webView * parent)1330 KviKvsWebView::KviKvsWebView(QWidget * par, const char * name, KvsObject_webView * parent)
1331 : QWebView(par)
1332 {
1333 m_pParentScript = parent;
1334 setObjectName(name);
1335 }
1336
mouseMoveEvent(QMouseEvent * ev)1337 void KviKvsWebView::mouseMoveEvent(QMouseEvent * ev)
1338 {
1339 KviKvsVariant vRetValue;
1340 KviKvsVariantList lParams;
1341 lParams.append(new KviKvsVariant((kvs_int_t)ev->x()));
1342 lParams.append(new KviKvsVariant((kvs_int_t)ev->y()));
1343 if(!m_pParentScript->callFunction(m_pParentScript, "mouseMoveEvent", &vRetValue, &lParams))
1344 QWebView::mouseMoveEvent(ev); // ignore results of a broken event handler
1345 else
1346 {
1347 if(!vRetValue.asBoolean())
1348 QWebView::mouseMoveEvent(ev);
1349 }
1350 }
contextMenuEvent(QContextMenuEvent * ev)1351 void KviKvsWebView::contextMenuEvent(QContextMenuEvent * ev)
1352 {
1353 KviKvsVariant vRetValue;
1354 KviKvsVariantList lParams;
1355 lParams.append(new KviKvsVariant((kvs_int_t)ev->x()));
1356 lParams.append(new KviKvsVariant((kvs_int_t)ev->y()));
1357 if(!m_pParentScript->callFunction(m_pParentScript, "customContextMenuRequestedEvent", &vRetValue, &lParams))
1358 QWebView::contextMenuEvent(ev); // ignore results of a broken event handler
1359 else
1360 {
1361 if(!vRetValue.asBoolean())
1362 QWebView::contextMenuEvent(ev);
1363 }
1364 }
event(QEvent * e)1365 bool KviKvsWebView::event(QEvent * e)
1366 {
1367
1368 if(e->type() == QEvent::ToolTip)
1369 {
1370 QHelpEvent * helpEvent = static_cast<QHelpEvent *>(e);
1371 QString szTooltip = "";
1372 KviKvsVariant * tipret = new KviKvsVariant(szTooltip);
1373 KviKvsVariantList params(new KviKvsVariant((kvs_int_t)helpEvent->x()), new KviKvsVariant((kvs_int_t)helpEvent->y()));
1374 m_pParentScript->callFunction(m_pParentScript, "maybeTipEvent", tipret, ¶ms);
1375 tipret->asString(szTooltip);
1376 if(!szTooltip.isEmpty())
1377 {
1378 QToolTip::showText(helpEvent->globalPos(), szTooltip);
1379 return false;
1380 }
1381 }
1382 return QWebView::event(e);
1383 }
1384 KviKvsWebView::~KviKvsWebView()
1385 = default;
1386 #endif // COMPILE_WEBKIT_SUPPORT
1387