void InsertIntoTextNodeCommand::doApply(EditingState*) {
  bool passwordEchoEnabled =
      document().settings() && document().settings()->passwordEchoEnabled();
  if (passwordEchoEnabled)
    document().updateStyleAndLayoutIgnorePendingStylesheets();

  if (!hasEditableStyle(*m_node))
    return;

  if (passwordEchoEnabled) {
    LayoutText* layoutText = m_node->layoutObject();
    if (layoutText && layoutText->isSecure())
      layoutText->momentarilyRevealLastTypedCharacter(m_offset +
                                                      m_text.length() - 1);
  }

  m_node->insertData(m_offset, m_text, IGNORE_EXCEPTION);
  document().updateStyleAndLayout();
}
Exemple #2
0
TEST_F(VisualRectMappingTest, LayoutView) {
  document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
  setBodyInnerHTML(
      "<style>body { margin: 0; }</style>"
      "<div id=frameContainer>"
      "  <iframe src='http://test.com' width='50' height='50' "
      "frameBorder='0'></iframe>"
      "</div>");
  setChildFrameHTML(
      "<style>body { margin: 0; }</style><span><img style='width: 20px; "
      "height: 100px'></span>text text text");

  document().view()->updateAllLifecyclePhases();

  LayoutBlock* frameContainer =
      toLayoutBlock(getLayoutObjectByElementId("frameContainer"));
  LayoutBlock* frameBody =
      toLayoutBlock(childDocument().body()->layoutObject());
  LayoutText* frameText = toLayoutText(frameBody->lastChild());

  // This case involves clipping: frame height is 50, y-coordinate of result
  // rect is 13, so height should be clipped to (50 - 13) == 37.
  childDocument().view()->setScrollOffset(ScrollOffset(0, 47),
                                          ProgrammaticScroll);
  LayoutRect originalRect(4, 60, 20, 80);
  LayoutRect rect = originalRect;
  EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect));
  EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37));

  rect = originalRect;
  EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(&layoutView(), rect));
  EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37));
  checkPaintInvalidationStateRectMapping(rect, originalRect, *frameText,
                                         layoutView(), layoutView());

  rect = LayoutRect(4, 60, 0, 80);
  EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect,
                                                        EdgeInclusive));
  EXPECT_EQ(rect, LayoutRect(4, 13, 0, 37));
}
LayoutText* SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::handleFirstLetter(int& startOffset, int& offsetInNode)
{
    LayoutText* layoutObject = toLayoutText(m_node->layoutObject());
    startOffset = (m_node == m_startNode) ? m_startOffset : 0;

    if (!layoutObject->isTextFragment()) {
        offsetInNode = 0;
        return layoutObject;
    }

    LayoutTextFragment* fragment = toLayoutTextFragment(layoutObject);
    int offsetAfterFirstLetter = fragment->start();
    if (startOffset >= offsetAfterFirstLetter) {
        ASSERT(!m_shouldHandleFirstLetter);
        offsetInNode = offsetAfterFirstLetter;
        return layoutObject;
    }

    if (!m_shouldHandleFirstLetter && offsetAfterFirstLetter < m_offset) {
        m_shouldHandleFirstLetter = true;
        offsetInNode = offsetAfterFirstLetter;
        return layoutObject;
    }

    m_shouldHandleFirstLetter = false;
    offsetInNode = 0;

    ASSERT(fragment->isRemainingTextLayoutObject());
    ASSERT(fragment->firstLetterPseudoElement());

    LayoutObject* pseudoElementLayoutObject = fragment->firstLetterPseudoElement()->layoutObject();
    ASSERT(pseudoElementLayoutObject);
    ASSERT(pseudoElementLayoutObject->slowFirstChild());
    LayoutText* firstLetterLayoutObject = toLayoutText(pseudoElementLayoutObject->slowFirstChild());

    m_offset = firstLetterLayoutObject->caretMaxOffset();
    m_offset += collapsedSpaceLength(firstLetterLayoutObject, m_offset);

    return firstLetterLayoutObject;
}
TextRun SVGInlineTextBox::constructTextRun(const ComputedStyle& style, const SVGTextFragment& fragment) const
{
    LayoutText* text = &layoutObject();

    // FIXME(crbug.com/264211): This should not be necessary but can occur if we
    //                          layout during layout. Remove this when 264211 is fixed.
    RELEASE_ASSERT(!text->needsLayout());

    TextRun run(static_cast<const LChar*>(0) // characters, will be set below if non-zero.
        , 0 // length, will be set below if non-zero.
        , 0 // xPos, only relevant with allowTabs=true
        , 0 // padding, only relevant for justified text, not relevant for SVG
        , TextRun::AllowTrailingExpansion
        , direction()
        , dirOverride() || style.rtlOrdering() == VisualOrder /* directionalOverride */);

    if (fragment.length) {
        if (text->is8Bit())
            run.setText(text->characters8() + fragment.characterOffset, fragment.length);
        else
            run.setText(text->characters16() + fragment.characterOffset, fragment.length);
    }

    // We handle letter & word spacing ourselves.
    run.disableSpacing();

    // Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring.
    run.setCharactersLength(text->textLength() - fragment.characterOffset);
    ASSERT(run.charactersLength() >= run.length());
    return run;
}
void LayoutTreeBuilderForText::createLayoutObject()
{
    ComputedStyle& style = m_layoutObjectParent->mutableStyleRef();

    ASSERT(m_node->textLayoutObjectIsNeeded(style, *m_layoutObjectParent));

    LayoutText* newLayoutObject = m_node->createTextLayoutObject(style);
    if (!m_layoutObjectParent->isChildAllowed(newLayoutObject, style)) {
        newLayoutObject->destroy();
        return;
    }

    // Make sure the LayoutObject already knows it is going to be added to a LayoutFlowThread before we set the style
    // for the first time. Otherwise code using inLayoutFlowThread() in the styleWillChange and styleDidChange will fail.
    newLayoutObject->setIsInsideFlowThread(m_layoutObjectParent->isInsideFlowThread());

    LayoutObject* nextLayoutObject = this->nextLayoutObject();
    m_node->setLayoutObject(newLayoutObject);
    // Parent takes care of the animations, no need to call setAnimatableStyle.
    newLayoutObject->setStyle(&style);
    m_layoutObjectParent->addChild(newLayoutObject, nextLayoutObject);
}