ginebra2/ChromeDOM.cpp
changeset 0 1450b09d0cfd
child 3 0954f5dd2cd0
child 5 0f2326c2a325
equal deleted inserted replaced
-1:000000000000 0:1450b09d0cfd
       
     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