15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (C) 2000 Dirk Mueller (mueller@kde.org)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTextFragment.h"
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Text.h"
271e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/rendering/HitTestResult.h"
2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderBlock.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderTextFragment::RenderTextFragment(Node* node, StringImpl* str, int startOffset, int length)
33d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    : RenderText(node, str ? str->substring(startOffset, length) : PassRefPtr<StringImpl>(nullptr))
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_start(startOffset)
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_end(length)
36e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    , m_firstLetter(nullptr)
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderTextFragment::RenderTextFragment(Node* node, StringImpl* str)
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : RenderText(node, str)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_start(0)
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_end(str ? str->length() : 0)
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_contentString(str)
45e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    , m_firstLetter(nullptr)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderTextFragment::~RenderTextFragment()
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
53e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void RenderTextFragment::trace(Visitor* visitor)
54e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){
55e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    visitor->trace(m_firstLetter);
56e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RenderText::trace(visitor);
57e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)}
58e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)RenderText* RenderTextFragment::firstRenderTextInFirstLetter() const
601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    for (RenderObject* current = m_firstLetter; current; current = current->nextInPreOrder(m_firstLetter)) {
621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (current->isText())
631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)            return toRenderText(current);
641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    }
651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return 0;
661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> RenderTextFragment::originalText() const
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Node* e = node();
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<StringImpl> result = ((e && e->isTextNode()) ? toText(e)->dataImpl() : contentString());
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!result)
73d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return result->substring(start(), end());
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTextFragment::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderText::styleDidChange(diff, oldStyle);
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (RenderBlock* block = blockForAccompanyingFirstLetter()) {
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        block->style()->removeCachedPseudoStyle(FIRST_LETTER);
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        block->updateFirstLetter();
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTextFragment::willBeDestroyed()
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_firstLetter)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_firstLetter->destroy();
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderText::willBeDestroyed();
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTextFragment::setText(PassRefPtr<StringImpl> text, bool force)
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderText::setText(text, force);
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_start = 0;
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_end = textLength();
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_firstLetter) {
101323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        // FIXME: We should not modify the structure of the render tree during
102323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        // layout. crbug.com/370458
103323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        DeprecatedDisableModifyRenderTreeStructureAsserts disabler;
104323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!m_contentString);
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_firstLetter->destroy();
107e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        m_firstLetter = nullptr;
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (Node* t = node()) {
109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            ASSERT(!t->renderer());
110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            t->setRenderer(this);
111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void RenderTextFragment::transformText()
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Don't reset first-letter here because we are only transforming the truncated fragment.
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (RefPtr<StringImpl> textToTransform = originalText())
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RenderText::setText(textToTransform.release(), true);
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)UChar RenderTextFragment::previousCharacter() const
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (start()) {
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Node* e = node();
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        StringImpl* original = ((e && e->isTextNode()) ? toText(e)->dataImpl() : contentString());
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (original && start() <= original->length())
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return (*original)[start() - 1];
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return RenderText::previousCharacter();
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderBlock* RenderTextFragment::blockForAccompanyingFirstLetter() const
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_firstLetter)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (RenderObject* block = m_firstLetter->parent(); block; block = block->parent()) {
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (block->style()->hasPseudoStyle(FIRST_LETTER) && block->canHaveChildren() && block->isRenderBlock())
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return toRenderBlock(block);
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return 0;
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)void RenderTextFragment::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
1461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){
1471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (result.innerNode())
1481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return;
1491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    RenderObject::updateHitTestResult(result, point);
1511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (m_firstLetter || !node())
1521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return;
1531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    RenderObject* nodeRenderer = node()->renderer();
1541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (!nodeRenderer || !nodeRenderer->isText() || !toRenderText(nodeRenderer)->isTextFragment())
1551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        return;
1561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
1571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    if (isDescendantOf(toRenderTextFragment(nodeRenderer)->m_firstLetter))
1581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        result.setIsFirstLetter(true);
1591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)}
1601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
161c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
162