|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <QtGui> |
|
20 #include <QWebElement> |
|
21 #include <QWebFrame> |
|
22 #include <QWebPage> |
|
23 |
|
24 #include "ChromeDOM.h" |
|
25 #include "ChromeRenderer.h" |
|
26 #include "ChromeSnippet.h" |
|
27 #include "ChromeWidget.h" |
|
28 #include "WebChromeSnippet.h" |
|
29 #include "WebChromeContainerSnippet.h" |
|
30 #include "GreenChromeSnippet.h" |
|
31 #include "BlueChromeSnippet.h" |
|
32 #include "ScrollZoomWidget.h" |
|
33 #include "ProgressSnippet.h" |
|
34 #include "TextEditItem.h" |
|
35 #include "ToolbarChromeItem.h" |
|
36 #include "ContentToolbarChromeItem.h" |
|
37 #include "iconsnippet.h" |
|
38 #include "iconwidget.h" |
|
39 #include "ActionButton.h" |
|
40 #include "UrlSearchSnippet.h" |
|
41 #include "ActionButtonSnippet.h" |
|
42 #include "mostvisitedpageview.h" |
|
43 #include "mostvisitedsnippet.h" |
|
44 |
|
45 #include <QDebug> |
|
46 |
|
47 //TODO: Replace JS strings with DOM api. Make stateful: i.e. get the doc element from the current page |
|
48 |
|
49 namespace GVA { |
|
50 |
|
51 ChromeDOM::ChromeDOM(QWebPage * page, ChromeWidget * chrome) |
|
52 : m_page(page), |
|
53 m_chrome(chrome), |
|
54 m_height(0), |
|
55 m_bytes(0) |
|
56 { |
|
57 m_renderer = m_chrome->renderer(); |
|
58 m_renderer->clearRenderList(); |
|
59 } |
|
60 |
|
61 ChromeDOM::~ChromeDOM() |
|
62 { |
|
63 } |
|
64 |
|
65 QVariant ChromeDOM::evalInChromeContext(QString js){ |
|
66 return m_page->mainFrame()->evaluateJavaScript(js); |
|
67 } |
|
68 |
|
69 QWebElement ChromeDOM::getElementById(const QString &id) |
|
70 { |
|
71 return m_page->mainFrame()->documentElement().findFirst("#" + id); |
|
72 } |
|
73 |
|
74 QRect ChromeDOM::getElementRect(const QString &id) |
|
75 { |
|
76 return getElementById(id).geometry(); |
|
77 } |
|
78 |
|
79 QSize ChromeDOM::getElementSize(const QString &id) |
|
80 { |
|
81 QRect rect = getElementRect(id); |
|
82 return QSize(rect.width(), rect.height()); |
|
83 } |
|
84 |
|
85 QString ChromeDOM::getElementAttribute(const QString &id, const QString &attribute) |
|
86 { |
|
87 return getElementById(id).attribute(attribute); |
|
88 } |
|
89 |
|
90 //Get the cacheable script element. Only one is allowed so get the first one. |
|
91 /*QString ChromeDOM::getCacheableScript() |
|
92 { |
|
93 QWebElement doc = m_page->mainFrame()->documentElement(); |
|
94 return doc.findAll("script.GinebraCacheable").toList()[0].toPlainText(); |
|
95 } |
|
96 */ |
|
97 |
|
98 //Get a list of cached handlers for a snippet |
|
99 |
|
100 QList<CachedHandler> ChromeDOM::getCachedHandlers(const QString &elementId, const QRectF & ownerArea) |
|
101 { |
|
102 QWebElement snippet = getElementById(elementId); |
|
103 QList <QWebElement> controls = snippet.findAll(".GinebraCached").toList(); |
|
104 QList <CachedHandler> handlers; |
|
105 for(int i = 0; i < controls.size(); i++){ |
|
106 QWebElement elem = controls.at(i); |
|
107 //Element rectangle relative to snippet, so we can handle mouse events relative to snippet |
|
108 //qDebug() << "====> Owner X: " << ownerArea.x() << " Owner Width: " << ownerArea.width() << " Elem X: " << elem.geometry().x() << " Elem Width: " << elem.geometry().width(); |
|
109 QRectF elemRect(elem.geometry().x() - ownerArea.x(), elem.geometry().y() - ownerArea.y(), elem.geometry().width(), elem.geometry().height()); |
|
110 //NB: For now we handle only onclick from cache. Should add at least long-press too. |
|
111 CachedHandler handler(elem.attribute("id"), elem.attribute("data-GinebraOnClick"), elemRect, m_chrome, elem.attribute("data-GinebraTargetView")); |
|
112 //qDebug() << "Cached handler" << handler.elementId() << ": " << handler.script() << ": " << handler.rect(); |
|
113 handlers.append(handler); |
|
114 } |
|
115 return handlers; |
|
116 } |
|
117 |
|
118 ChromeSnippet *ChromeDOM::getSnippet(const QString &docElementId, QGraphicsItem* parent) { |
|
119 |
|
120 ChromeSnippet * result = 0; |
|
121 QWebElement doc = m_page->mainFrame()->documentElement(); |
|
122 QWebElement element = doc.findFirst("#" + docElementId); |
|
123 QRect rect = getElementRect(docElementId); |
|
124 m_height += rect.height(); |
|
125 //m_bytes += rect.width() * rect.height() * 3; //Calculate total rendered area at 24 bit depth |
|
126 //qDebug() << "Chrome total rects at 24 bits: " << m_bytes; |
|
127 //qDebug() << "Snippet: ID: " << docElementId << " Owner Area: " << rect << " Element Rect: " << element.geometry(); |
|
128 if(!rect.isNull()){ |
|
129 QString className = element.attribute("data-GinebraNativeClass", "__NO_CLASS__"); |
|
130 if(className == "__NO_CLASS__") |
|
131 if(element.attribute("data-GinebraContainer", "false") == "true" ){ |
|
132 |
|
133 QString type = element.attribute("data-GinebraItemType", "normal"); |
|
134 if (type == "contenttoolbar" ) { |
|
135 ContentToolbarChromeItem * widget = new ContentToolbarChromeItem(); |
|
136 result = new WebChromeContainerSnippet(docElementId, m_chrome, rect, element, widget); |
|
137 widget->setSnippet((WebChromeContainerSnippet*)result); |
|
138 } |
|
139 else if (type == "toolbar" ) { |
|
140 ToolbarChromeItem * widget = new ToolbarChromeItem(); |
|
141 result = new WebChromeContainerSnippet(docElementId, m_chrome, rect, element, widget); |
|
142 widget->setSnippet((WebChromeContainerSnippet*)result); |
|
143 } |
|
144 else { |
|
145 result = new WebChromeContainerSnippet(docElementId, m_chrome, rect, element, new QGraphicsWidget()); |
|
146 } |
|
147 } |
|
148 else { |
|
149 result = new WebChromeSnippet(docElementId, m_chrome, rect, element); |
|
150 m_renderer->addRenderItem((static_cast<WebChromeSnippet*>(result))->item()); |
|
151 } |
|
152 else { |
|
153 QGraphicsWidget * w = 0; |
|
154 if (className == "IconSnippet") { |
|
155 result = new IconSnippet(docElementId, m_chrome, 0, element); |
|
156 w = new IconWidget(result); |
|
157 } else if (className == "MostVisitedPagesWidget") { |
|
158 result = new MostVisitedSnippet(docElementId,m_chrome,0,element); |
|
159 MostVisitedPagesWidget* mostVisited; |
|
160 mostVisited = new MostVisitedPagesWidget(result,m_chrome); |
|
161 mostVisited->hide(); |
|
162 w = mostVisited; |
|
163 } else if (className == "ActionButton") { |
|
164 result = new ActionButtonSnippet(docElementId, m_chrome, 0, element); |
|
165 w = new ActionButton(result); |
|
166 } else { |
|
167 //Chrome snippet takes ownership of w |
|
168 result = new ChromeSnippet(docElementId, m_chrome, 0, element); |
|
169 if (className == "ScrollZoomWidget") |
|
170 w = new ScrollZoomWidget(result); |
|
171 else if (className == "UrlSearchSnippet") |
|
172 w = new UrlSearchSnippet(result, m_chrome); |
|
173 else if (className == "ProgressSnippet") |
|
174 w = new ProgressSnippet(result); |
|
175 else if (className == "TextEditSnippet"){ |
|
176 w = new TextEditItem(result); |
|
177 } |
|
178 else { |
|
179 w= new GreenChromeSnippet(); |
|
180 } |
|
181 } |
|
182 result->setWidget(w); |
|
183 //Have snippet deterimine its own size when in anchor layout |
|
184 w->resize(rect.width(), rect.height()); |
|
185 w->setPreferredSize(rect.width(), rect.height()); |
|
186 w->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); |
|
187 //Have snippet determine its own location when NOT in anchor layout |
|
188 w->setPos(rect.x(), rect.y()); |
|
189 } |
|
190 |
|
191 if(element.parent().attribute("class") == "GinebraSnippet") { |
|
192 result->setParentId(element.parent().attribute("id")); |
|
193 } |
|
194 //Set auto-layout attributes |
|
195 result->setAnchor(element.attribute("data-GinebraAnchor", "AnchorNone"), false); |
|
196 result->setAnchorOffset(element.attribute("data-GinebraAnchorOffset", "0").toInt()); |
|
197 result->setInitiallyVisible(element.attribute("data-GinebraVisible", "false") == "true" ); |
|
198 result->setHidesContent( element.attribute("data-GinebraHidesContent", "false") == "true" ); |
|
199 } |
|
200 return result; |
|
201 } |
|
202 |
|
203 QList <QWebElement> ChromeDOM::getInitialElements() |
|
204 { |
|
205 m_renderer->clearRenderList(); |
|
206 QWebElement test = getElementById("TestTableCell9"); |
|
207 //qDebug() << "TEST ELEMENT:" << test.toPlainText(); |
|
208 m_height = 0; |
|
209 QWebElement doc = m_page->mainFrame()->documentElement(); |
|
210 #if QT_VERSION < 0x040600 //TBD: Do we care, given that the dom api is not officially supported before 4.6? |
|
211 return doc.findAll(".GinebraSnippet"); |
|
212 #else |
|
213 return doc.findAll(".GinebraSnippet").toList(); |
|
214 #endif |
|
215 } |
|
216 |
|
217 } // end of namespace GVA |