ginebra2/ChromeDOM.cpp
changeset 0 1450b09d0cfd
child 3 0954f5dd2cd0
child 5 0f2326c2a325
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ginebra2/ChromeDOM.cpp	Tue May 04 12:39:35 2010 +0300
@@ -0,0 +1,217 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+#include <QtGui>
+#include <QWebElement>
+#include <QWebFrame>
+#include <QWebPage>
+
+#include "ChromeDOM.h"
+#include "ChromeRenderer.h"
+#include "ChromeSnippet.h"
+#include "ChromeWidget.h"
+#include "WebChromeSnippet.h"
+#include "WebChromeContainerSnippet.h"
+#include "GreenChromeSnippet.h"
+#include "BlueChromeSnippet.h"
+#include "ScrollZoomWidget.h"
+#include "ProgressSnippet.h"
+#include "TextEditItem.h"
+#include "ToolbarChromeItem.h"
+#include "ContentToolbarChromeItem.h"
+#include "iconsnippet.h"
+#include "iconwidget.h"
+#include "ActionButton.h"
+#include "UrlSearchSnippet.h"
+#include "ActionButtonSnippet.h"
+#include "mostvisitedpageview.h"
+#include "mostvisitedsnippet.h"
+
+#include <QDebug>
+
+//TODO: Replace JS strings with DOM api. Make stateful: i.e. get the doc element from the current page
+
+namespace GVA {
+
+  ChromeDOM::ChromeDOM(QWebPage * page, ChromeWidget * chrome)
+    : m_page(page),
+      m_chrome(chrome),
+      m_height(0),
+      m_bytes(0)
+  {
+    m_renderer = m_chrome->renderer();
+    m_renderer->clearRenderList();
+  }
+  
+  ChromeDOM::~ChromeDOM()
+  {
+  }
+
+  QVariant ChromeDOM::evalInChromeContext(QString js){
+    return m_page->mainFrame()->evaluateJavaScript(js);
+  }
+  
+  QWebElement ChromeDOM::getElementById(const QString &id)
+  {
+    return m_page->mainFrame()->documentElement().findFirst("#" + id);
+  }
+  
+  QRect ChromeDOM::getElementRect(const QString &id)
+  {
+    return getElementById(id).geometry();
+  }
+  
+  QSize ChromeDOM::getElementSize(const QString &id)
+  {
+    QRect rect = getElementRect(id);
+    return QSize(rect.width(), rect.height());
+  }
+  
+  QString ChromeDOM::getElementAttribute(const QString &id, const QString &attribute)
+  {
+    return getElementById(id).attribute(attribute);
+  }
+  
+  //Get the cacheable script element. Only one is allowed so get the first one.
+  /*QString ChromeDOM::getCacheableScript()
+  {
+    QWebElement doc = m_page->mainFrame()->documentElement();
+    return doc.findAll("script.GinebraCacheable").toList()[0].toPlainText();
+  }
+  */
+
+  //Get a list of cached handlers for a snippet
+  
+  QList<CachedHandler> ChromeDOM::getCachedHandlers(const QString &elementId, const QRectF & ownerArea)
+  {
+    QWebElement snippet = getElementById(elementId);
+    QList <QWebElement> controls =  snippet.findAll(".GinebraCached").toList();
+    QList <CachedHandler> handlers;
+    for(int i = 0; i < controls.size(); i++){
+      QWebElement elem = controls.at(i);
+      //Element rectangle relative to snippet, so we can handle mouse events relative to snippet
+      //qDebug() << "====> Owner X: " << ownerArea.x() << " Owner Width: " << ownerArea.width() << " Elem X: " << elem.geometry().x() << " Elem Width: " << elem.geometry().width();
+      QRectF elemRect(elem.geometry().x() - ownerArea.x(), elem.geometry().y() - ownerArea.y(), elem.geometry().width(), elem.geometry().height()); 
+      //NB: For now we handle only onclick from cache. Should add at least long-press too.
+      CachedHandler handler(elem.attribute("id"), elem.attribute("data-GinebraOnClick"), elemRect, m_chrome, elem.attribute("data-GinebraTargetView"));
+      //qDebug() << "Cached handler" << handler.elementId() << ": "  << handler.script() << ": "  << handler.rect();
+      handlers.append(handler);
+    }
+    return handlers;  
+  }
+  
+  ChromeSnippet *ChromeDOM::getSnippet(const QString &docElementId, QGraphicsItem* parent) {
+    
+    ChromeSnippet * result = 0;
+    QWebElement doc = m_page->mainFrame()->documentElement();
+    QWebElement element = doc.findFirst("#" + docElementId);
+    QRect rect = getElementRect(docElementId);
+    m_height += rect.height();
+    //m_bytes += rect.width() * rect.height() * 3; //Calculate total rendered area at 24 bit depth
+    //qDebug() << "Chrome total rects at 24 bits: " << m_bytes;
+    //qDebug() << "Snippet: ID: " << docElementId << " Owner Area: " << rect << " Element Rect: " << element.geometry();
+    if(!rect.isNull()){
+      QString className = element.attribute("data-GinebraNativeClass", "__NO_CLASS__");
+      if(className == "__NO_CLASS__")
+	if(element.attribute("data-GinebraContainer", "false") == "true" ){
+          
+          QString type = element.attribute("data-GinebraItemType", "normal");
+          if (type == "contenttoolbar" ) {
+            ContentToolbarChromeItem * widget = new ContentToolbarChromeItem();
+            result = new WebChromeContainerSnippet(docElementId, m_chrome, rect, element, widget);
+            widget->setSnippet((WebChromeContainerSnippet*)result);
+          }
+          else if (type == "toolbar" ) {
+            ToolbarChromeItem * widget = new ToolbarChromeItem();
+            result = new WebChromeContainerSnippet(docElementId, m_chrome, rect, element, widget);
+            widget->setSnippet((WebChromeContainerSnippet*)result);
+          }
+          else {
+            result = new WebChromeContainerSnippet(docElementId, m_chrome, rect, element, new QGraphicsWidget());
+          }
+	}
+	else {
+	  result = new WebChromeSnippet(docElementId, m_chrome, rect, element);
+	  m_renderer->addRenderItem((static_cast<WebChromeSnippet*>(result))->item());
+        }
+      else {
+	QGraphicsWidget * w = 0; 
+    if (className == "IconSnippet") {
+        result = new IconSnippet(docElementId, m_chrome, 0, element);
+        w = new IconWidget(result);
+    } else if (className == "MostVisitedPagesWidget") {
+        result = new MostVisitedSnippet(docElementId,m_chrome,0,element);
+        MostVisitedPagesWidget* mostVisited;
+        mostVisited = new MostVisitedPagesWidget(result,m_chrome);
+        mostVisited->hide();
+        w = mostVisited;
+    } else if (className == "ActionButton") {
+        result = new ActionButtonSnippet(docElementId, m_chrome, 0, element);
+        w = new ActionButton(result);
+    } else {
+	  //Chrome snippet takes ownership of w
+	  result = new ChromeSnippet(docElementId, m_chrome, 0, element);
+	  if (className == "ScrollZoomWidget")
+	    w = new ScrollZoomWidget(result);
+          else if (className == "UrlSearchSnippet")
+	    w = new UrlSearchSnippet(result, m_chrome);
+	  else if (className == "ProgressSnippet")
+	    w = new ProgressSnippet(result);
+	  else if (className == "TextEditSnippet"){
+	    w = new TextEditItem(result);
+	  }
+	  else { 
+	    w= new GreenChromeSnippet();
+	  }
+	}
+        result->setWidget(w);
+        //Have snippet deterimine its own size when in anchor layout
+        w->resize(rect.width(), rect.height());
+	w->setPreferredSize(rect.width(), rect.height());
+	w->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
+        //Have snippet determine its own location when NOT in anchor layout
+        w->setPos(rect.x(), rect.y());	
+      }
+
+      if(element.parent().attribute("class") == "GinebraSnippet") {
+	result->setParentId(element.parent().attribute("id"));
+      }
+      //Set auto-layout attributes
+      result->setAnchor(element.attribute("data-GinebraAnchor", "AnchorNone"), false);
+      result->setAnchorOffset(element.attribute("data-GinebraAnchorOffset", "0").toInt());
+      result->setInitiallyVisible(element.attribute("data-GinebraVisible", "false") == "true" );
+      result->setHidesContent( element.attribute("data-GinebraHidesContent", "false") == "true" );      
+    }
+    return result;
+  }
+  
+  QList <QWebElement> ChromeDOM::getInitialElements()
+  { 
+    m_renderer->clearRenderList();
+    QWebElement test = getElementById("TestTableCell9");
+    //qDebug() << "TEST ELEMENT:" << test.toPlainText();
+    m_height = 0;
+    QWebElement doc = m_page->mainFrame()->documentElement();
+#if QT_VERSION < 0x040600 //TBD: Do we care, given that the dom api is not officially supported before 4.6?
+    return doc.findAll(".GinebraSnippet");
+#else
+    return doc.findAll(".GinebraSnippet").toList();
+#endif
+  } 
+  
+} // end of namespace GVA