15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Portions are Copyright (C) 1998 Netscape Communications Corporation. 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Other contributors: 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Robert O'Callahan <roc+@cs.cmu.edu> 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * David Baron <dbaron@fas.harvard.edu> 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Christian Biesinger <cbiesinger@web.de> 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Randall Jesup <rjesup@wgate.com> 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Josh Soref <timeless@mac.com> 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boris Zbarsky <bzbarsky@mit.edu> 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Lesser General Public 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2.1 of the License, or (at your option) any later version. 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Lesser General Public License for more details. 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Lesser General Public 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License along with this library; if not, write to the Free Software 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Alternatively, the contents of this file may be used under the terms 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * of either the Mozilla Public License Version 1.1, found at 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (the "GPL"), in which case the provisions of the MPL or the GPL are 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * applicable instead of those above. If you wish to allow use of your 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version of this file only under the terms of one of those two 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * licenses (the MPL or the GPL) and not to allow others to use your 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version of this file under the LGPL, indicate your decision by 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * deletingthe provisions above and replace them with the notice and 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * other provisions required by the MPL or the GPL, as the case may be. 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * If you do not delete the provisions above, a recipient may use your 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version of this file under any of the LGPL, the MPL or the GPL. 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderMarquee.h" 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h" 5053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLMarqueeElement.h" 511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/frame/FrameView.h" 5251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/frame/UseCounter.h" 5353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderLayer.h" 5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderView.h" 5509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/LengthFunctions.h" 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 57c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames; 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)RenderMarquee::RenderMarquee(HTMLMarqueeElement* element) 628abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) : RenderBlockFlow(element) 63521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_currentLoop(0) 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_totalLoops(0) 6509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) , m_timer(element, &HTMLMarqueeElement::timerFired) 66521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_start(0) 67521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_end(0) 68521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_speed(0) 69521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_reset(false) 70521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_suspended(false) 71521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_stopped(false) 72521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) , m_direction(MAUTO) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) UseCounter::count(document(), UseCounter::HTMLMarqueeElement); 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderMarquee::~RenderMarquee() 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderMarquee::marqueeSpeed() const 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 83521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) int result = style()->marqueeSpeed(); 848abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (Node* node = this->node()) 858abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) result = std::max(result, toHTMLMarqueeElement(node)->minimumDelay()); 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)EMarqueeDirection RenderMarquee::direction() const 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: Support the CSS3 "auto" value for determining the direction of the marquee. 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // For now just map MAUTO to MBACKWARD 93521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) EMarqueeDirection result = style()->marqueeDirection(); 94521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) TextDirection dir = style()->direction(); 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result == MAUTO) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = MBACKWARD; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result == MFORWARD) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = (dir == LTR) ? MRIGHT : MLEFT; 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result == MBACKWARD) 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = (dir == LTR) ? MLEFT : MRIGHT; 10102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Now we have the real direction. Next we check to see if the increment is negative. 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If so, then we reverse the direction. 104521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) Length increment = style()->marqueeIncrement(); 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (increment.isNegative()) 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result = static_cast<EMarqueeDirection>(-result); 10702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool RenderMarquee::isHorizontal() const 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return direction() == MLEFT || direction() == MRIGHT; 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int RenderMarquee::computePosition(EMarqueeDirection dir, bool stopAtContentEdge) 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isHorizontal()) { 119521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) bool ltr = style()->isLeftToRightDirection(); 120521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) LayoutUnit clientWidth = this->clientWidth(); 121521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) LayoutUnit contentWidth = ltr ? maxPreferredLogicalWidth() : minPreferredLogicalWidth(); 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ltr) 123521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) contentWidth += (paddingRight() - borderLeft()); 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 125521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) contentWidth = width() - contentWidth; 126521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) contentWidth += (paddingLeft() - borderRight()); 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (dir == MRIGHT) { 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stopAtContentEdge) 130197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return std::max<LayoutUnit>(0, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth)); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ltr ? contentWidth : clientWidth; 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stopAtContentEdge) 136197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return std::min<LayoutUnit>(0, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth)); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ltr ? -clientWidth : -contentWidth; 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 142521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) int contentHeight = layoutOverflowRect().maxY() - borderTop() + paddingBottom(); 143521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) int clientHeight = this->clientHeight(); 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (dir == MUP) { 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stopAtContentEdge) 146197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return std::min(contentHeight - clientHeight, 0); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -clientHeight; 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stopAtContentEdge) 152197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return std::max(contentHeight - clientHeight, 0); 15302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch else 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return contentHeight; 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch } 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMarquee::start() 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 161521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (m_timer.isActive() || style()->marqueeIncrement().isZero()) 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_suspended && !m_stopped) { 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isHorizontal()) 166bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) layer()->scrollableArea()->scrollToOffset(IntSize(m_start, 0)); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 168bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) layer()->scrollableArea()->scrollToOffset(IntSize(0, m_start)); 1691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } else { 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_suspended = false; 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_stopped = false; 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 174d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_timer.startRepeating(speed() * 0.001, FROM_HERE); 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMarquee::suspend() 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_timer.stop(); 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_suspended = true; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMarquee::stop() 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_timer.stop(); 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_stopped = true; 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderMarquee::updateMarqueePosition() 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool activate = (m_totalLoops <= 0 || m_currentLoop < m_totalLoops); 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (activate) { 193521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) EMarqueeBehavior behavior = style()->marqueeBehavior(); 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_start = computePosition(direction(), behavior == MALTERNATE); 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_end = computePosition(reverseDirection(), behavior == MALTERNATE || behavior == MSLIDE); 196d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!m_stopped) { 197d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Hits in compositing/overflow/do-not-repaint-if-scrolling-composited-layers.html during layout. 198d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) DisableCompositingQueryAsserts disabler; 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) start(); 200d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 204521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)const char* RenderMarquee::renderName() const 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 206521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (isFloating()) 207521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return "RenderMarquee (floating)"; 208521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (isOutOfFlowPositioned()) 209521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return "RenderMarquee (positioned)"; 210521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (isAnonymous()) 211521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return "RenderMarquee (generated)"; 212521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (isRelPositioned()) 213521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return "RenderMarquee (relative positioned)"; 214521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return "RenderMarquee"; 215521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 216521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 217521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 218521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void RenderMarquee::styleDidChange(StyleDifference difference, const RenderStyle* oldStyle) 219521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 22009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderBlockFlow::styleDidChange(difference, oldStyle); 221521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 222521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) RenderStyle* s = style(); 22302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_direction != s->marqueeDirection() || (m_totalLoops != s->marqueeLoopCount() && m_currentLoop >= m_totalLoops)) 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_currentLoop = 0; // When direction changes or our loopCount is a smaller number than our current loop, reset our loop. 22602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_totalLoops = s->marqueeLoopCount(); 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_direction = s->marqueeDirection(); 22902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 230521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Hack for WinIE. In WinIE, a value of 0 or lower for the loop count for SLIDE means to only do 231521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // one loop. 232521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (m_totalLoops <= 0 && s->marqueeBehavior() == MSLIDE) 233521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_totalLoops = 1; 234521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 235521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Hack alert: Set the white-space value to nowrap for horizontal marquees with inline children, thus ensuring 236521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // all the text ends up on one line by default. Limit this hack to the <marquee> element to emulate 237521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // WinIE's behavior. Someone using CSS3 can use white-space: nowrap on their own to get this effect. 238521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // Second hack alert: Set the text-align back to auto. WinIE completely ignores text-align on the 239521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // marquee element. 240521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // FIXME: Bring these up with the CSS WG. 241521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (isHorizontal() && childrenInline()) { 242521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) s->setWhiteSpace(NOWRAP); 243521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) s->setTextAlign(TASTART); 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 245521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Legacy hack - multiple browsers default vertical marquees to 200px tall. 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isHorizontal() && s->height().isAuto()) 24802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch s->setHeight(Length(200, Fixed)); 24902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (speed() != marqueeSpeed()) { 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_speed = marqueeSpeed(); 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_timer.isActive()) 253d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_timer.startRepeating(speed() * 0.001, FROM_HERE); 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 25502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check the loop count to see if we should now stop. 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool activate = (m_totalLoops <= 0 || m_currentLoop < m_totalLoops); 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (activate && !m_timer.isActive()) 2595d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) setNeedsLayoutAndFullPaintInvalidation(); 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (!activate && m_timer.isActive()) 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_timer.stop(); 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 26409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void RenderMarquee::layoutBlock(bool relayoutChildren) 265591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 26609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderBlockFlow::layoutBlock(relayoutChildren); 267591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 268591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch updateMarqueePosition(); 269591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 270591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 27109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void RenderMarquee::timerFired() 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 273521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // FIXME: Why do we need to check the view and not just the RenderMarquee itself? 274521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) if (view()->needsLayout()) 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 27602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_reset) { 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_reset = false; 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isHorizontal()) 280bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) layer()->scrollableArea()->scrollToXOffset(m_start); 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 282bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) layer()->scrollableArea()->scrollToYOffset(m_start); 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 28502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 286521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) RenderStyle* s = style(); 28702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int endPoint = m_end; 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int range = m_end - m_start; 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int newPos; 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (range == 0) 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newPos = m_end; 29302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch else { 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool addIncrement = direction() == MUP || direction() == MLEFT; 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool isReversed = s->marqueeBehavior() == MALTERNATE && m_currentLoop % 2; 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isReversed) { 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We're going in the reverse direction. 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endPoint = m_start; 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) range = -range; 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) addIncrement = !addIncrement; 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool positive = range > 0; 303521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) int clientSize = (isHorizontal() ? clientWidth() : clientHeight()); 304521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) int increment = abs(intValueForLength(style()->marqueeIncrement(), clientSize)); 305bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) int currentPos = (isHorizontal() ? layer()->scrollableArea()->scrollXOffset() : layer()->scrollableArea()->scrollYOffset()); 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newPos = currentPos + (addIncrement ? increment : -increment); 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (positive) 308197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch newPos = std::min(newPos, endPoint); 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 310197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch newPos = std::max(newPos, endPoint); 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (newPos == endPoint) { 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_currentLoop++; 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_totalLoops > 0 && m_currentLoop >= m_totalLoops) 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_timer.stop(); 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (s->marqueeBehavior() != MALTERNATE) 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_reset = true; 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 32002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isHorizontal()) 322bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) layer()->scrollableArea()->scrollToXOffset(newPos); 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 324bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) layer()->scrollableArea()->scrollToYOffset(newPos); 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 327c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 328