ginebra2/ChromeDOM.cpp
changeset 5 0f2326c2a325
parent 0 1450b09d0cfd
child 6 1c3b8676e58c
equal deleted inserted replaced
1:b0dd75e285d2 5:0f2326c2a325
     1 /*
     1 /*
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 *
     5 * under the terms of "Eclipse Public License v1.0"
     5 * This program is free software: you can redistribute it and/or modify
     6 * which accompanies this distribution, and is available
     6 * it under the terms of the GNU Lesser General Public License as published by
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * the Free Software Foundation, version 2.1 of the License.
     8 *
     8 *
     9 * Initial Contributors:
     9 * This program is distributed in the hope that it will be useful,
    10 * Nokia Corporation - initial contribution.
    10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11 *
    11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12 * Contributors:
    12 * GNU Lesser General Public License for more details.
    13 *
    13 *
    14 * Description: 
    14 * You should have received a copy of the GNU Lesser General Public License
       
    15 * along with this program.  If not,
       
    16 * see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
       
    17 *
       
    18 * Description:
    15 *
    19 *
    16 */
    20 */
    17 
       
    18 
    21 
    19 #include <QtGui>
    22 #include <QtGui>
    20 #include <QWebElement>
    23 #include <QWebElement>
    21 #include <QWebFrame>
    24 #include <QWebFrame>
    22 #include <QWebPage>
    25 #include <QWebPage>
    25 #include "ChromeRenderer.h"
    28 #include "ChromeRenderer.h"
    26 #include "ChromeSnippet.h"
    29 #include "ChromeSnippet.h"
    27 #include "ChromeWidget.h"
    30 #include "ChromeWidget.h"
    28 #include "WebChromeSnippet.h"
    31 #include "WebChromeSnippet.h"
    29 #include "WebChromeContainerSnippet.h"
    32 #include "WebChromeContainerSnippet.h"
    30 #include "GreenChromeSnippet.h"
    33 #include "PageSnippet.h"
    31 #include "BlueChromeSnippet.h"
    34 #include "PageItem.h"
    32 #include "ScrollZoomWidget.h"
    35 #include "ProgressBarItem.h"
    33 #include "ProgressSnippet.h"
    36 #include "ProgressBarSnippet.h"
    34 #include "TextEditItem.h"
       
    35 #include "ToolbarChromeItem.h"
    37 #include "ToolbarChromeItem.h"
    36 #include "ContentToolbarChromeItem.h"
    38 #include "ContentToolbarChromeItem.h"
    37 #include "iconsnippet.h"
    39 #include "ContentToolbarSnippet.h"
    38 #include "iconwidget.h"
    40 #include "WindowToolbarSnippet.h"
       
    41 #include "RecentUrlToolbarSnippet.h"
       
    42 #include "BookmarksToolbarSnippet.h"
       
    43 #include "SettingsToolbarSnippet.h"
    39 #include "ActionButton.h"
    44 #include "ActionButton.h"
    40 #include "UrlSearchSnippet.h"
       
    41 #include "ActionButtonSnippet.h"
    45 #include "ActionButtonSnippet.h"
    42 #include "mostvisitedpageview.h"
    46 #include "mostvisitedpageview.h"
    43 #include "mostvisitedsnippet.h"
    47 #include "mostvisitedsnippet.h"
       
    48 #include "UrlSearchSnippet.h"
       
    49 #include "EditorSnippet.h"
    44 
    50 
    45 #include <QDebug>
    51 #include <QDebug>
    46 
    52 
    47 //TODO: Replace JS strings with DOM api. Make stateful: i.e. get the doc element from the current page
    53 //TODO: Replace JS strings with DOM api. Make stateful: i.e. get the doc element from the current page
    48 
    54 
    55       m_bytes(0)
    61       m_bytes(0)
    56   {
    62   {
    57     m_renderer = m_chrome->renderer();
    63     m_renderer = m_chrome->renderer();
    58     m_renderer->clearRenderList();
    64     m_renderer->clearRenderList();
    59   }
    65   }
    60   
    66 
    61   ChromeDOM::~ChromeDOM()
    67   ChromeDOM::~ChromeDOM()
    62   {
    68   {
    63   }
    69   }
    64 
    70 
    65   QVariant ChromeDOM::evalInChromeContext(QString js){
    71   QVariant ChromeDOM::evalInChromeContext(QString js){
    66     return m_page->mainFrame()->evaluateJavaScript(js);
    72     return m_page->mainFrame()->evaluateJavaScript(js);
    67   }
    73   }
    68   
    74 
    69   QWebElement ChromeDOM::getElementById(const QString &id)
    75   QWebElement ChromeDOM::getElementById(const QString &id)
    70   {
    76   {
    71     return m_page->mainFrame()->documentElement().findFirst("#" + id);
    77     return m_page->mainFrame()->documentElement().findFirst("#" + id);
    72   }
    78   }
    73   
    79 
    74   QRect ChromeDOM::getElementRect(const QString &id)
    80   QRect ChromeDOM::getElementRect(const QString &id)
    75   {
    81   {
    76     return getElementById(id).geometry();
    82     return getElementById(id).geometry();
    77   }
    83   }
    78   
    84 
    79   QSize ChromeDOM::getElementSize(const QString &id)
    85   QSize ChromeDOM::getElementSize(const QString &id)
    80   {
    86   {
    81     QRect rect = getElementRect(id);
    87     QRect rect = getElementRect(id);
    82     return QSize(rect.width(), rect.height());
    88     return QSize(rect.width(), rect.height());
    83   }
    89   }
    84   
    90 
    85   QString ChromeDOM::getElementAttribute(const QString &id, const QString &attribute)
    91   QString ChromeDOM::getElementAttribute(const QString &id, const QString &attribute)
    86   {
    92   {
    87     return getElementById(id).attribute(attribute);
    93     return getElementById(id).attribute(attribute);
    88   }
    94   }
    89   
    95 
    90   //Get the cacheable script element. Only one is allowed so get the first one.
    96   //Get the cacheable script element. Only one is allowed so get the first one.
    91   /*QString ChromeDOM::getCacheableScript()
    97   /*QString ChromeDOM::getCacheableScript()
    92   {
    98   {
    93     QWebElement doc = m_page->mainFrame()->documentElement();
    99     QWebElement doc = m_page->mainFrame()->documentElement();
    94     return doc.findAll("script.GinebraCacheable").toList()[0].toPlainText();
   100     return doc.findAll("script.GinebraCacheable").toList()[0].toPlainText();
    95   }
   101   }
    96   */
   102   */
    97 
   103 
    98   //Get a list of cached handlers for a snippet
   104   //Get a list of cached handlers for a snippet
    99   
   105 
   100   QList<CachedHandler> ChromeDOM::getCachedHandlers(const QString &elementId, const QRectF & ownerArea)
   106   QList<CachedHandler> ChromeDOM::getCachedHandlers(const QString &elementId, const QRectF & ownerArea)
   101   {
   107   {
   102     QWebElement snippet = getElementById(elementId);
   108     QWebElement snippet = getElementById(elementId);
   103     QList <QWebElement> controls =  snippet.findAll(".GinebraCached").toList();
   109     QList <QWebElement> controls =  snippet.findAll(".GinebraCached").toList();
   104     QList <CachedHandler> handlers;
   110     QList <CachedHandler> handlers;
   105     for(int i = 0; i < controls.size(); i++){
   111     for (int i = 0; i < controls.size(); i++){
   106       QWebElement elem = controls.at(i);
   112       QWebElement elem = controls.at(i);
   107       //Element rectangle relative to snippet, so we can handle mouse events relative to snippet
   113       //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();
   114       //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()); 
   115       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.
   116       //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"));
   117       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();
   118       //qDebug() << "Cached handler" << handler.elementId() << ": "  << handler.script() << ": "  << handler.rect();
   113       handlers.append(handler);
   119       handlers.append(handler);
   114     }
   120     }
   115     return handlers;  
   121     return handlers;
   116   }
   122   }
   117   
   123 
   118   ChromeSnippet *ChromeDOM::getSnippet(const QString &docElementId, QGraphicsItem* parent) {
   124   ChromeSnippet *ChromeDOM::getSnippet(const QString &docElementId, QGraphicsItem* parent) {
   119     
   125     Q_UNUSED(parent)
       
   126 
   120     ChromeSnippet * result = 0;
   127     ChromeSnippet * result = 0;
   121     QWebElement doc = m_page->mainFrame()->documentElement();
   128     QWebElement doc = m_page->mainFrame()->documentElement();
   122     QWebElement element = doc.findFirst("#" + docElementId);
   129     QWebElement element = doc.findFirst("#" + docElementId);
   123     QRect rect = getElementRect(docElementId);
   130     QRect rect = element.geometry();//getElementRect(docElementId);
   124     m_height += rect.height();
   131     m_height += rect.height();
   125     //m_bytes += rect.width() * rect.height() * 3; //Calculate total rendered area at 24 bit depth
   132     //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;
   133     //qDebug() << "Chrome total rects at 24 bits: " << m_bytes;
   127     //qDebug() << "Snippet: ID: " << docElementId << " Owner Area: " << rect << " Element Rect: " << element.geometry();
   134     //    qDebug() << "Snippet: ID: " << docElementId << " Owner Area: " << rect << " Element Rect: " << element.geometry();
   128     if(!rect.isNull()){
   135     if (!rect.isNull()) {
   129       QString className = element.attribute("data-GinebraNativeClass", "__NO_CLASS__");
   136         QString className = element.attribute("data-GinebraNativeClass", "__NO_CLASS__");
   130       if(className == "__NO_CLASS__")
   137         if (className == "__NO_CLASS__") {
   131 	if(element.attribute("data-GinebraContainer", "false") == "true" ){
   138             if (element.attribute("data-GinebraContainer", "false") == "true") {
   132           
   139                 ChromeItem * widget = new ChromeItem(NULL);
   133           QString type = element.attribute("data-GinebraItemType", "normal");
   140                 result = new WebChromeContainerSnippet(docElementId, m_chrome, rect, element,
   134           if (type == "contenttoolbar" ) {
   141                     widget);
   135             ContentToolbarChromeItem * widget = new ContentToolbarChromeItem();
   142                 widget->setSnippet(result);
   136             result = new WebChromeContainerSnippet(docElementId, m_chrome, rect, element, widget);
   143             }
   137             widget->setSnippet((WebChromeContainerSnippet*)result);
   144             else {
   138           }
   145                 result = new WebChromeSnippet(docElementId, m_chrome, rect, element);
   139           else if (type == "toolbar" ) {
   146                 m_renderer->addRenderItem((static_cast<WebChromeSnippet*> (result))->item());
   140             ToolbarChromeItem * widget = new ToolbarChromeItem();
   147             }
   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         }
   148         }
   152       else {
   149         else {
   153 	QGraphicsWidget * w = 0; 
   150      
   154     if (className == "IconSnippet") {
   151             if (className == "ContentToolbar" ) {
   155         result = new IconSnippet(docElementId, m_chrome, 0, element);
   152                 ContentToolbarChromeItem * widget = new ContentToolbarChromeItem();
   156         w = new IconWidget(result);
   153                 result = new ContentToolbarSnippet(docElementId, m_chrome, rect, element, widget);
   157     } else if (className == "MostVisitedPagesWidget") {
   154                 widget->setSnippet(result);
   158         result = new MostVisitedSnippet(docElementId,m_chrome,0,element);
   155             }
   159         MostVisitedPagesWidget* mostVisited;
   156             else if (className == "WindowToolbar" ) {
   160         mostVisited = new MostVisitedPagesWidget(result,m_chrome);
   157                 ToolbarChromeItem * widget = new ToolbarChromeItem();
   161         mostVisited->hide();
   158                 result = new WindowToolbarSnippet(docElementId, m_chrome, rect, element, widget);
   162         w = mostVisited;
   159                 widget->setSnippet(result);
   163     } else if (className == "ActionButton") {
   160             }
   164         result = new ActionButtonSnippet(docElementId, m_chrome, 0, element);
   161             else if (className == "RecentUrlToolbar" ) {
   165         w = new ActionButton(result);
   162                 ToolbarChromeItem * widget = new ToolbarChromeItem();
   166     } else {
   163                 result = new RecentUrlToolbarSnippet(docElementId, m_chrome, rect, element, widget);
   167 	  //Chrome snippet takes ownership of w
   164                 widget->setSnippet(result);
   168 	  result = new ChromeSnippet(docElementId, m_chrome, 0, element);
   165             }
   169 	  if (className == "ScrollZoomWidget")
   166             else if (className == "BookmarksToolbar" ) {
   170 	    w = new ScrollZoomWidget(result);
   167                 ToolbarChromeItem * widget = new ToolbarChromeItem();
   171           else if (className == "UrlSearchSnippet")
   168                 result = new BookmarksToolbarSnippet(docElementId, m_chrome, rect, element, widget);
   172 	    w = new UrlSearchSnippet(result, m_chrome);
   169                 widget->setSnippet(result);
   173 	  else if (className == "ProgressSnippet")
   170             }
   174 	    w = new ProgressSnippet(result);
   171             else if (className == "SettingsToolbar" ) {
   175 	  else if (className == "TextEditSnippet"){
   172                 ToolbarChromeItem * widget = new ToolbarChromeItem();
   176 	    w = new TextEditItem(result);
   173                 result = new SettingsToolbarSnippet(docElementId, m_chrome, rect, element, widget);
   177 	  }
   174                 widget->setSnippet(result);
   178 	  else { 
   175             }
   179 	    w= new GreenChromeSnippet();
   176             else if (className == "ToolBar" ) {
   180 	  }
   177                 ToolbarChromeItem * widget = new ToolbarChromeItem();
   181 	}
   178                 result = new WebChromeContainerSnippet(docElementId, m_chrome, rect, element,
   182         result->setWidget(w);
   179                     widget);
   183         //Have snippet deterimine its own size when in anchor layout
   180                 widget->setSnippet(result);
   184         w->resize(rect.width(), rect.height());
   181             }
   185 	w->setPreferredSize(rect.width(), rect.height());
   182             else {
   186 	w->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
   183                 QGraphicsWidget * w = 0;
   187         //Have snippet determine its own location when NOT in anchor layout
   184                 if (className == "MostVisitedPagesWidget") {
   188         w->setPos(rect.x(), rect.y());	
   185                     result = new MostVisitedSnippet(docElementId, m_chrome, 0, element);
   189       }
   186                     MostVisitedPagesWidget* mostVisited;
   190 
   187                     mostVisited = new MostVisitedPagesWidget(result, m_chrome);
   191       if(element.parent().attribute("class") == "GinebraSnippet") {
   188                     mostVisited->hide();
   192 	result->setParentId(element.parent().attribute("id"));
   189                     w = mostVisited;
   193       }
   190                 }
   194       //Set auto-layout attributes
   191                 else if (className == "ActionButton") {
   195       result->setAnchor(element.attribute("data-GinebraAnchor", "AnchorNone"), false);
   192                     result = new ActionButtonSnippet(docElementId, m_chrome, 0, element);
   196       result->setAnchorOffset(element.attribute("data-GinebraAnchorOffset", "0").toInt());
   193                     w = new ActionButton(result);
   197       result->setInitiallyVisible(element.attribute("data-GinebraVisible", "false") == "true" );
   194                 }
   198       result->setHidesContent( element.attribute("data-GinebraHidesContent", "false") == "true" );      
   195                 else if (className == "PageSnippet") {
       
   196                     result = new PageSnippet(docElementId, m_chrome, 0, element);
       
   197                     w = new PageItem(result, m_chrome);
       
   198                 }
       
   199                 else if (className == "ProgressBar") {
       
   200                     result = new ProgressBarSnippet(docElementId, m_chrome, 0, element);
       
   201                     w = new ProgressBarItem(result);
       
   202                 }
       
   203                 else if (className == "UrlSearchSnippet") {
       
   204                     result = new GUrlSearchSnippet(docElementId, m_chrome, 0, element);
       
   205                     w = new GUrlSearchItem(result, m_chrome);
       
   206                 }
       
   207                 else if (className == "TextEditSnippet") {
       
   208                     result = new EditorSnippet(docElementId, m_chrome, 0, element);
       
   209                     w = new TextEditItem(result, m_chrome);
       
   210                 }
       
   211                 else {
       
   212                     //Chrome snippet takes ownership of w
       
   213                     result = new ChromeSnippet(docElementId, m_chrome, 0, element);
       
   214                     w = new QGraphicsWidget();
       
   215                 }
       
   216                 result->setWidget(w);
       
   217                 //Have snippet deterimine its own size when in anchor layout
       
   218                 w->resize(rect.width(), rect.height());
       
   219                 w->setPreferredSize(rect.width(), rect.height());
       
   220                 w->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
       
   221                 //Have snippet determine its own location when NOT in anchor layout
       
   222                 w->setPos(rect.x(), rect.y());
       
   223             }
       
   224         }
       
   225 
       
   226         QWebElement parentElem;
       
   227 
       
   228         if (!(parentElem = findChromeParent(element)).isNull()) {
       
   229             result->setParentId(parentElem.attribute("id"));
       
   230         }
       
   231         //Set auto-layout attributes
       
   232         result->setAnchor(element.attribute("data-GinebraAnchor", "AnchorNone"), false);
       
   233         result->setAnchorOffset(element.attribute("data-GinebraAnchorOffset", "0").toInt());
       
   234         result->setInitiallyVisible(element.attribute("data-GinebraVisible", "false") == "true");
       
   235         result->setHidesContent(element.attribute("data-GinebraHidesContent", "false") == "true");
   199     }
   236     }
   200     return result;
   237     return result;
   201   }
   238   }
   202   
   239   
       
   240   QWebElement ChromeDOM::findChromeParent(QWebElement element)
       
   241   {
       
   242     while(!(element = element.parent()).isNull()){
       
   243       if (element.attribute("class") == "GinebraSnippet"){
       
   244 	return element;
       
   245       }
       
   246     }
       
   247     return element;
       
   248   }
       
   249 
   203   QList <QWebElement> ChromeDOM::getInitialElements()
   250   QList <QWebElement> ChromeDOM::getInitialElements()
   204   { 
   251   {
   205     m_renderer->clearRenderList();
   252     m_renderer->clearRenderList();
   206     QWebElement test = getElementById("TestTableCell9");
   253     QWebElement test = getElementById("TestTableCell9");
   207     //qDebug() << "TEST ELEMENT:" << test.toPlainText();
   254     //qDebug() << "TEST ELEMENT:" << test.toPlainText();
   208     m_height = 0;
   255     m_height = 0;
   209     QWebElement doc = m_page->mainFrame()->documentElement();
   256     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?
   257 #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");
   258     return doc.findAll(".GinebraSnippet");
   212 #else
   259 #else
   213     return doc.findAll(".GinebraSnippet").toList();
   260     return doc.findAll(".GinebraSnippet").toList();
   214 #endif
   261 #endif
   215   } 
   262   }
   216   
   263 
   217 } // end of namespace GVA
   264 } // end of namespace GVA