18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. 3231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Portions are Copyright (C) 1998 Netscape Communications Corporation. 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Other contributors: 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Robert O'Callahan <roc+@cs.cmu.edu> 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * David Baron <dbaron@fas.harvard.edu> 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Christian Biesinger <cbiesinger@web.de> 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Randall Jesup <rjesup@wgate.com> 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Josh Soref <timeless@mac.com> 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boris Zbarsky <bzbarsky@mit.edu> 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Lesser General Public 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2.1 of the License, or (at your option) any later version. 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Lesser General Public License for more details. 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Lesser General Public 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License along with this library; if not, write to the Free Software 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Alternatively, the contents of this file may be used under the terms 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * of either the Mozilla Public License Version 1.1, found at 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (the "GPL"), in which case the provisions of the MPL or the GPL are 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * applicable instead of those above. If you wish to allow use of your 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version of this file only under the terms of one of those two 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * licenses (the MPL or the GPL) and not to allow others to use your 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version of this file under the LGPL, indicate your decision by 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * deletingthe provisions above and replace them with the notice and 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * other provisions required by the MPL or the GPL, as the case may be. 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * If you do not delete the provisions above, a recipient may use your 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version of this file under any of the LGPL, the MPL or the GPL. 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderMarquee.h" 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameView.h" 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLMarqueeElement.h" 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h" 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderLayer.h" 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace std; 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames; 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRenderMarquee::RenderMarquee(RenderLayer* l) 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project : m_layer(l), m_currentLoop(0) 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_totalLoops(0) 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_timer(this, &RenderMarquee::timerFired) 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_start(0), m_end(0), m_speed(0), m_reset(false) 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_suspended(false), m_stopped(false), m_direction(MAUTO) 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 69a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochRenderMarquee::~RenderMarquee() 70a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{ 71a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} 72a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderMarquee::marqueeSpeed() const 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int result = m_layer->renderer()->style()->marqueeSpeed(); 768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Node* n = m_layer->renderer()->node(); 778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (n && n->hasTagName(marqueeTag)) { 788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian HTMLMarqueeElement* marqueeElt = static_cast<HTMLMarqueeElement*>(n); 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = max(result, marqueeElt->minimumDelay()); 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectEMarqueeDirection RenderMarquee::direction() const 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Support the CSS3 "auto" value for determining the direction of the marquee. 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // For now just map MAUTO to MBACKWARD 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project EMarqueeDirection result = m_layer->renderer()->style()->marqueeDirection(); 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project TextDirection dir = m_layer->renderer()->style()->direction(); 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result == MAUTO) 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = MBACKWARD; 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result == MFORWARD) 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = (dir == LTR) ? MRIGHT : MLEFT; 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result == MBACKWARD) 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = (dir == LTR) ? MLEFT : MRIGHT; 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Now we have the real direction. Next we check to see if the increment is negative. 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If so, then we reverse the direction. 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Length increment = m_layer->renderer()->style()->marqueeIncrement(); 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (increment.isNegative()) 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = static_cast<EMarqueeDirection>(-result); 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RenderMarquee::isHorizontal() const 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return direction() == MLEFT || direction() == MRIGHT; 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint RenderMarquee::computePosition(EMarqueeDirection dir, bool stopAtContentEdge) 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderBox* box = m_layer->renderBox(); 1148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ASSERT(box); 1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RenderStyle* s = box->style(); 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isHorizontal()) { 117a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch bool ltr = s->isLeftToRightDirection(); 1188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int clientWidth = box->clientWidth(); 1192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int contentWidth = ltr ? box->maxXLayoutOverflow() : box->minXLayoutOverflow(); 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ltr) 1218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian contentWidth += (box->paddingRight() - box->borderLeft()); 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian contentWidth = box->width() - contentWidth; 1248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian contentWidth += (box->paddingLeft() - box->borderRight()); 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (dir == MRIGHT) { 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (stopAtContentEdge) 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return max(0, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth)); 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return ltr ? contentWidth : clientWidth; 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (stopAtContentEdge) 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return min(0, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth)); 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return ltr ? -clientWidth : -contentWidth; 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block int contentHeight = box->maxYLayoutOverflow() - box->borderTop() + box->paddingBottom(); 1418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int clientHeight = box->clientHeight(); 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (dir == MUP) { 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (stopAtContentEdge) 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return min(contentHeight - clientHeight, 0); 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return -clientHeight; 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (stopAtContentEdge) 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return max(contentHeight - clientHeight, 0); 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return contentHeight; 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderMarquee::start() 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 159231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_timer.isActive() || m_layer->renderer()->style()->marqueeIncrement().isZero() 160231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(WCSS) && ENABLE(XHTMLMP) 161231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block || (m_layer->renderer()->document()->isXHTMLMPDocument() && !m_layer->renderer()->style()->marqueeLoopCount()) 162231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif 163231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ) 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We may end up propagating a scroll event. It is important that we suspend events until 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // the end of the function since they could delete the layer, including the marquee. 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FrameView* frameView = m_layer->renderer()->document()->view(); 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (frameView) 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project frameView->pauseScheduledEvents(); 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_suspended && !m_stopped) { 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isHorizontal()) 174ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch m_layer->scrollToOffset(m_start, 0); 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 176ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch m_layer->scrollToOffset(0, m_start); 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_suspended = false; 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_stopped = false; 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_timer.startRepeating(speed() * 0.001); 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (frameView) 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project frameView->resumeScheduledEvents(); 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderMarquee::suspend() 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_timer.stop(); 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_suspended = true; 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderMarquee::stop() 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_timer.stop(); 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_stopped = true; 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderMarquee::updateMarqueePosition() 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool activate = (m_totalLoops <= 0 || m_currentLoop < m_totalLoops); 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (activate) { 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project EMarqueeBehavior behavior = m_layer->renderer()->style()->marqueeBehavior(); 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_start = computePosition(direction(), behavior == MALTERNATE); 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_end = computePosition(reverseDirection(), behavior == MALTERNATE || behavior == MSLIDE); 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_stopped) 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project start(); 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderMarquee::updateMarqueeStyle() 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderStyle* s = m_layer->renderer()->style(); 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_direction != s->marqueeDirection() || (m_totalLoops != s->marqueeLoopCount() && m_currentLoop >= m_totalLoops)) 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_currentLoop = 0; // When direction changes or our loopCount is a smaller number than our current loop, reset our loop. 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_totalLoops = s->marqueeLoopCount(); 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_direction = s->marqueeDirection(); 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_layer->renderer()->isHTMLMarquee()) { 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Hack for WinIE. In WinIE, a value of 0 or lower for the loop count for SLIDE means to only do 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // one loop. 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_totalLoops <= 0 && s->marqueeBehavior() == MSLIDE) 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_totalLoops = 1; 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Hack alert: Set the white-space value to nowrap for horizontal marquees with inline children, thus ensuring 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // all the text ends up on one line by default. Limit this hack to the <marquee> element to emulate 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // WinIE's behavior. Someone using CSS3 can use white-space: nowrap on their own to get this effect. 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Second hack alert: Set the text-align back to auto. WinIE completely ignores text-align on the 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // marquee element. 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: Bring these up with the CSS WG. 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isHorizontal() && m_layer->renderer()->childrenInline()) { 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project s->setWhiteSpace(NOWRAP); 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project s->setTextAlign(TAAUTO); 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Marquee height hack!! Make sure that, if it is a horizontal marquee, the height attribute is overridden 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // if it is smaller than the font size. If it is a vertical marquee and height is not specified, we default 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // to a marquee of 200px. 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isHorizontal()) { 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (s->height().isFixed() && s->height().value() < s->fontSize()) 2460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch s->setHeight(Length(s->fontSize(), Fixed)); 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else if (s->height().isAuto()) //vertical marquee with no specified height 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project s->setHeight(Length(200, Fixed)); 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (speed() != marqueeSpeed()) { 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_speed = marqueeSpeed(); 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_timer.isActive()) 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_timer.startRepeating(speed() * 0.001); 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Check the loop count to see if we should now stop. 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool activate = (m_totalLoops <= 0 || m_currentLoop < m_totalLoops); 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (activate && !m_timer.isActive()) 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_layer->renderer()->setNeedsLayout(true); 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (!activate && m_timer.isActive()) 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_timer.stop(); 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid RenderMarquee::timerFired(Timer<RenderMarquee>*) 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_layer->renderer()->needsLayout()) 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_reset) { 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_reset = false; 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isHorizontal()) 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_layer->scrollToXOffset(m_start); 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_layer->scrollToYOffset(m_start); 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RenderStyle* s = m_layer->renderer()->style(); 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int endPoint = m_end; 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int range = m_end - m_start; 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int newPos; 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (range == 0) 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newPos = m_end; 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else { 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool addIncrement = direction() == MUP || direction() == MLEFT; 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool isReversed = s->marqueeBehavior() == MALTERNATE && m_currentLoop % 2; 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isReversed) { 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We're going in the reverse direction. 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project endPoint = m_start; 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project range = -range; 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project addIncrement = !addIncrement; 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool positive = range > 0; 2958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int clientSize = (isHorizontal() ? m_layer->renderBox()->clientWidth() : m_layer->renderBox()->clientHeight()); 296f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int increment = abs(m_layer->renderer()->style()->marqueeIncrement().calcValue(clientSize)); 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int currentPos = (isHorizontal() ? m_layer->scrollXOffset() : m_layer->scrollYOffset()); 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newPos = currentPos + (addIncrement ? increment : -increment); 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (positive) 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newPos = min(newPos, endPoint); 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newPos = max(newPos, endPoint); 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (newPos == endPoint) { 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_currentLoop++; 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_totalLoops > 0 && m_currentLoop >= m_totalLoops) 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_timer.stop(); 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if (s->marqueeBehavior() != MALTERNATE) 3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_reset = true; 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isHorizontal()) 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_layer->scrollToXOffset(newPos); 3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_layer->scrollToYOffset(newPos); 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 320