Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: Source/core/editing/markup.cpp

Issue 24278008: [oilpan] Handlify Nodes in htmlediting (Closed) Base URL: svn://svn.chromium.org/blink/branches/oilpan
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2008, 2009, 2010, 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2008, 2009, 2010, 2011 Google Inc. All rights reserved.
4 * Copyright (C) 2011 Igalia S.L. 4 * Copyright (C) 2011 Igalia S.L.
5 * Copyright (C) 2011 Motorola Mobility. All rights reserved. 5 * Copyright (C) 2011 Motorola Mobility. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 : MarkupAccumulator(nodes, shouldResolveURLs, range) 162 : MarkupAccumulator(nodes, shouldResolveURLs, range)
163 , m_shouldAnnotate(shouldAnnotate) 163 , m_shouldAnnotate(shouldAnnotate)
164 , m_highestNodeToBeSerialized(highestNodeToBeSerialized) 164 , m_highestNodeToBeSerialized(highestNodeToBeSerialized)
165 { 165 {
166 } 166 }
167 167
168 void StyledMarkupAccumulator::wrapWithNode(Node* node, bool convertBlocksToInlin es, RangeFullySelectsNode rangeFullySelectsNode) 168 void StyledMarkupAccumulator::wrapWithNode(Node* node, bool convertBlocksToInlin es, RangeFullySelectsNode rangeFullySelectsNode)
169 { 169 {
170 StringBuilder markup; 170 StringBuilder markup;
171 if (node->isElementNode()) 171 if (node->isElementNode())
172 appendElement(markup, adoptRawResult(toElement(node)), convertBlocksToIn lines && isBlock(const_cast<Node*>(node)), rangeFullySelectsNode); 172 appendElement(markup, adoptRawResult(toElement(node)), convertBlocksToIn lines && isBlock(adoptRawResult(const_cast<Node*>(node))), rangeFullySelectsNode );
173 else 173 else
174 appendStartMarkup(markup, node, 0); 174 appendStartMarkup(markup, node, 0);
175 m_reversedPrecedingMarkup.append(markup.toString()); 175 m_reversedPrecedingMarkup.append(markup.toString());
176 appendEndTag(node); 176 appendEndTag(node);
177 if (m_nodes) 177 if (m_nodes)
178 m_nodes->append(node); 178 m_nodes->append(node);
179 } 179 }
180 180
181 void StyledMarkupAccumulator::wrapWithStyleNode(const Handle<StylePropertySet>& style, const Handle<Document>& document, bool isBlock) 181 void StyledMarkupAccumulator::wrapWithStyleNode(const Handle<StylePropertySet>& style, const Handle<Document>& document, bool isBlock)
182 { 182 {
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 // past pastEnd and become null here. This shouldn't be possible. 360 // past pastEnd and become null here. This shouldn't be possible.
361 // This null check will prevent crashes (but create too much markup) 361 // This null check will prevent crashes (but create too much markup)
362 // and the ASSERT will hopefully lead us to understanding the problem. 362 // and the ASSERT will hopefully lead us to understanding the problem.
363 ASSERT(n); 363 ASSERT(n);
364 if (!n) 364 if (!n)
365 break; 365 break;
366 366
367 next = NodeTraversal::next(n); 367 next = NodeTraversal::next(n);
368 bool openedTag = false; 368 bool openedTag = false;
369 369
370 if (isBlock(n.raw()) && canHaveChildrenForEditing(n.raw()) && next == pa stEnd) 370 if (isBlock(n) && canHaveChildrenForEditing(n) && next == pastEnd)
371 // Don't write out empty block containers that aren't fully selected . 371 // Don't write out empty block containers that aren't fully selected .
372 continue; 372 continue;
373 373
374 if (!n->renderer() && !enclosingNodeWithTag(firstPositionInOrBeforeNode( n.raw()), selectTag)) { 374 if (!n->renderer() && !enclosingNodeWithTag(firstPositionInOrBeforeNode( n), selectTag)) {
375 next = NodeTraversal::nextSkippingChildren(n); 375 next = NodeTraversal::nextSkippingChildren(n);
376 // Don't skip over pastEnd. 376 // Don't skip over pastEnd.
377 if (pastEnd && pastEnd->isDescendantOf(n.raw())) 377 if (pastEnd && pastEnd->isDescendantOf(n.raw()))
378 next = adoptRawResult(pastEnd); 378 next = adoptRawResult(pastEnd);
379 } else { 379 } else {
380 // Add the node to the markup if we're not skipping the descendants 380 // Add the node to the markup if we're not skipping the descendants
381 if (shouldEmit) 381 if (shouldEmit)
382 appendStartTag(n.raw()); 382 appendStartTag(n.raw());
383 383
384 // If node has no children, close the tag now. 384 // If node has no children, close the tag now.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 wrapWithNode(parent.raw()); 421 wrapWithNode(parent.raw());
422 lastClosed = parent; 422 lastClosed = parent;
423 } 423 }
424 } 424 }
425 } 425 }
426 } 426 }
427 427
428 return lastClosed.raw(); 428 return lastClosed.raw();
429 } 429 }
430 430
431 static bool isHTMLBlockElement(const Node* node) 431 static bool isHTMLBlockElement(const Handle<const Node>& node)
432 { 432 {
433 return node->hasTagName(tdTag) 433 return node->hasTagName(tdTag)
434 || node->hasTagName(thTag) 434 || node->hasTagName(thTag)
435 || isNonTableCellHTMLBlockElement(node); 435 || isNonTableCellHTMLBlockElement(node);
436 } 436 }
437 437
438 static Node* ancestorToRetainStructureAndAppearanceForBlock(Node* commonAncestor Block) 438 static Result<Node> ancestorToRetainStructureAndAppearanceForBlock(const Handle< Node>& commonAncestorBlock)
439 { 439 {
440 if (!commonAncestorBlock) 440 if (!commonAncestorBlock)
441 return 0; 441 return nullptr;
442 442
443 if (commonAncestorBlock->hasTagName(tbodyTag) || commonAncestorBlock->hasTag Name(trTag)) { 443 if (commonAncestorBlock->hasTagName(tbodyTag) || commonAncestorBlock->hasTag Name(trTag)) {
444 Handle<ContainerNode> table = commonAncestorBlock->parentNode(); 444 Handle<ContainerNode> table = commonAncestorBlock->parentNode();
445 while (table && !table->hasTagName(tableTag)) 445 while (table && !table->hasTagName(tableTag)) {
446 NoHandleScope scope;
446 table = table->parentNode(); 447 table = table->parentNode();
448 }
447 449
448 return table.raw(); 450 return table;
449 } 451 }
450 452
451 if (isNonTableCellHTMLBlockElement(commonAncestorBlock)) 453 if (isNonTableCellHTMLBlockElement(commonAncestorBlock))
452 return commonAncestorBlock; 454 return commonAncestorBlock;
453 455
454 return 0; 456 return nullptr;
455 } 457 }
456 458
457 static inline Node* ancestorToRetainStructureAndAppearance(Node* commonAncestor) 459 static inline Result<Node> ancestorToRetainStructureAndAppearance(const Handle<N ode>& commonAncestor)
458 { 460 {
459 return ancestorToRetainStructureAndAppearanceForBlock(enclosingBlock(commonA ncestor).handle().raw()); 461 return ancestorToRetainStructureAndAppearanceForBlock(enclosingBlock(commonA ncestor));
460 } 462 }
461 463
462 static inline Node* ancestorToRetainStructureAndAppearanceWithNoRenderer(Node* c ommonAncestor) 464 static inline Result<Node> ancestorToRetainStructureAndAppearanceWithNoRenderer( const Handle<Node>& commonAncestor)
463 { 465 {
464 Node* commonAncestorBlock = enclosingNodeOfType(firstPositionInOrBeforeNode( commonAncestor), isHTMLBlockElement); 466 Handle<Node> commonAncestorBlock = enclosingNodeOfType(firstPositionInOrBefo reNode(commonAncestor), isHTMLBlockElement);
465 return ancestorToRetainStructureAndAppearanceForBlock(commonAncestorBlock); 467 return ancestorToRetainStructureAndAppearanceForBlock(commonAncestorBlock);
466 } 468 }
467 469
468 static bool propertyMissingOrEqualToNone(const Handle<StylePropertySet>& style, CSSPropertyID propertyID) 470 static bool propertyMissingOrEqualToNone(const Handle<StylePropertySet>& style, CSSPropertyID propertyID)
469 { 471 {
470 if (!style) 472 if (!style)
471 return false; 473 return false;
472 Handle<CSSValue> value = style->getPropertyCSSValue(propertyID); 474 Handle<CSSValue> value = style->getPropertyCSSValue(propertyID);
473 if (!value) 475 if (!value)
474 return true; 476 return true;
(...skipping 17 matching lines...) Expand all
492 return 0; 494 return 0;
493 495
494 // FIXME: Having to const_cast here is ugly, but it is quite a bit of work t o untangle 496 // FIXME: Having to const_cast here is ugly, but it is quite a bit of work t o untangle
495 // the non-const-ness of styleFromMatchedRulesForElement. 497 // the non-const-ness of styleFromMatchedRulesForElement.
496 Handle<HTMLElement> element = toHTMLElement(Handle<Node>::constCast(adoptRaw Result(node))); 498 Handle<HTMLElement> element = toHTMLElement(Handle<Node>::constCast(adoptRaw Result(node)));
497 RefPtr<EditingStyle> style = EditingStyle::createFromPropertySet(element->in lineStyle()); 499 RefPtr<EditingStyle> style = EditingStyle::createFromPropertySet(element->in lineStyle());
498 style->mergeStyleFromRules(element); 500 style->mergeStyleFromRules(element);
499 return style.release(); 501 return style.release();
500 } 502 }
501 503
502 static bool isElementPresentational(const Node* node) 504 static bool isElementPresentational(const Handle<const Node>& node)
503 { 505 {
504 return node->hasTagName(uTag) || node->hasTagName(sTag) || node->hasTagName( strikeTag) 506 return node->hasTagName(uTag) || node->hasTagName(sTag) || node->hasTagName( strikeTag)
505 || node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName (bTag) || node->hasTagName(strongTag); 507 || node->hasTagName(iTag) || node->hasTagName(emTag) || node->hasTagName (bTag) || node->hasTagName(strongTag);
506 } 508 }
507 509
508 static Node* highestAncestorToWrapMarkup(const Handle<const Range>& range, EAnno tateForInterchange shouldAnnotate, Node* constrainingAncestor) 510 static Node* highestAncestorToWrapMarkup(const Handle<const Range>& range, EAnno tateForInterchange shouldAnnotate, Node* constrainingAncestor)
509 { 511 {
510 Handle<Node> commonAncestor = range->commonAncestorContainer(IGNORE_EXCEPTIO N); 512 Handle<Node> commonAncestor = range->commonAncestorContainer(IGNORE_EXCEPTIO N);
511 ASSERT(commonAncestor); 513 ASSERT(commonAncestor);
512 Handle<Node> specialCommonAncestor; 514 Handle<Node> specialCommonAncestor;
513 if (shouldAnnotate == AnnotateForInterchange) { 515 if (shouldAnnotate == AnnotateForInterchange) {
514 // Include ancestors that aren't completely inside the range but are req uired to retain 516 // Include ancestors that aren't completely inside the range but are req uired to retain
515 // the structure and appearance of the copied markup. 517 // the structure and appearance of the copied markup.
516 specialCommonAncestor = adoptRawResult(ancestorToRetainStructureAndAppea rance(commonAncestor.raw())); 518 specialCommonAncestor = ancestorToRetainStructureAndAppearance(commonAnc estor);
517 519
518 if (Node* parentListNode = enclosingNodeOfType(firstPositionInOrBeforeNo de(range->firstNode().handle().raw()), isListItem)) { 520 if (Handle<Node> parentListNode = enclosingNodeOfType(firstPositionInOrB eforeNode(range->firstNode()), isListItem)) {
519 if (WebCore::areRangesEqual(VisibleSelection::selectionFromContentsO fNode(parentListNode).toNormalizedRange(), range)) { 521 if (WebCore::areRangesEqual(VisibleSelection::selectionFromContentsO fNode(parentListNode.raw()).toNormalizedRange(), range)) {
520 specialCommonAncestor = parentListNode->parentNode(); 522 specialCommonAncestor = parentListNode->parentNode();
521 while (specialCommonAncestor && !isListElement(specialCommonAnce stor.raw())) { 523 while (specialCommonAncestor && !isListElement(specialCommonAnce stor)) {
522 NoHandleScope scope; 524 NoHandleScope scope;
523 specialCommonAncestor = specialCommonAncestor->parentNode(); 525 specialCommonAncestor = specialCommonAncestor->parentNode();
524 } 526 }
525 } 527 }
526 } 528 }
527 529
528 // Retain the Mail quote level by including all ancestor mail block quot es. 530 // Retain the Mail quote level by including all ancestor mail block quot es.
529 if (Handle<Node> highestMailBlockquote = adoptRawResult(highestEnclosing NodeOfType(firstPositionInOrBeforeNode(range->firstNode().handle().raw()), isMai lBlockquote, CanCrossEditingBoundary))) 531 if (Handle<Node> highestMailBlockquote = highestEnclosingNodeOfType(firs tPositionInOrBeforeNode(range->firstNode()), isMailBlockquote, CanCrossEditingBo undary))
530 specialCommonAncestor = highestMailBlockquote; 532 specialCommonAncestor = highestMailBlockquote;
531 } 533 }
532 534
533 Handle<Node> checkAncestor = specialCommonAncestor ? specialCommonAncestor : commonAncestor; 535 Handle<Node> checkAncestor = specialCommonAncestor ? specialCommonAncestor : commonAncestor;
534 if (checkAncestor->renderer()) { 536 if (checkAncestor->renderer()) {
535 Handle<Node> newSpecialCommonAncestor = adoptRawResult(highestEnclosingN odeOfType(firstPositionInNode(checkAncestor), &isElementPresentational, CanCross EditingBoundary, constrainingAncestor)); 537 Handle<Node> newSpecialCommonAncestor = highestEnclosingNodeOfType(first PositionInNode(checkAncestor), &isElementPresentational, CanCrossEditingBoundary , adoptRawResult(constrainingAncestor));
536 if (newSpecialCommonAncestor) 538 if (newSpecialCommonAncestor)
537 specialCommonAncestor = newSpecialCommonAncestor; 539 specialCommonAncestor = newSpecialCommonAncestor;
538 } 540 }
539 541
540 // If a single tab is selected, commonAncestor will be a text node inside a tab span. 542 // If a single tab is selected, commonAncestor will be a text node inside a tab span.
541 // If two or more tabs are selected, commonAncestor will be the tab span. 543 // If two or more tabs are selected, commonAncestor will be the tab span.
542 // In either case, if there is a specialCommonAncestor already, it will nece ssarily be above 544 // In either case, if there is a specialCommonAncestor already, it will nece ssarily be above
543 // any tab span that needs to be included. 545 // any tab span that needs to be included.
544 if (!specialCommonAncestor && isTabSpanTextNode(commonAncestor.raw())) 546 if (!specialCommonAncestor && isTabSpanTextNode(commonAncestor))
545 specialCommonAncestor = commonAncestor->parentNode(); 547 specialCommonAncestor = commonAncestor->parentNode();
546 if (!specialCommonAncestor && isTabSpanNode(commonAncestor.raw())) 548 if (!specialCommonAncestor && isTabSpanNode(commonAncestor))
547 specialCommonAncestor = commonAncestor; 549 specialCommonAncestor = commonAncestor;
548 550
549 if (Handle<Node> enclosingAnchor = adoptRawResult(enclosingNodeWithTag(first PositionInNode(specialCommonAncestor ? specialCommonAncestor : commonAncestor), aTag))) 551 if (Handle<Node> enclosingAnchor = enclosingNodeWithTag(firstPositionInNode( specialCommonAncestor ? specialCommonAncestor : commonAncestor), aTag))
550 specialCommonAncestor = enclosingAnchor; 552 specialCommonAncestor = enclosingAnchor;
551 553
552 return specialCommonAncestor.raw(); 554 return specialCommonAncestor.raw();
553 } 555 }
554 556
555 // FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForIntercha nge? 557 // FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForIntercha nge?
556 // FIXME: At least, annotation and style info should probably not be included in range.markupString() 558 // FIXME: At least, annotation and style info should probably not be included in range.markupString()
557 static String createMarkupInternal(const Handle<Document>& document, const Handl e<const Range>& range, const Handle<const Range>& updatedRange, Vector<Node*>* n odes, 559 static String createMarkupInternal(const Handle<Document>& document, const Handl e<const Range>& range, const Handle<const Range>& updatedRange, Vector<Node*>* n odes,
558 EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsolu teURLs shouldResolveURLs, Node* constrainingAncestor) 560 EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsolu teURLs shouldResolveURLs, Node* constrainingAncestor)
559 { 561 {
560 ASSERT(document); 562 ASSERT(document);
561 ASSERT(range); 563 ASSERT(range);
562 ASSERT(updatedRange); 564 ASSERT(updatedRange);
563 DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, (ASCIILiteral("< br class=\"" AppleInterchangeNewline "\">"))); 565 DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, (ASCIILiteral("< br class=\"" AppleInterchangeNewline "\">")));
564 566
565 bool collapsed = updatedRange->collapsed(ASSERT_NO_EXCEPTION); 567 bool collapsed = updatedRange->collapsed(ASSERT_NO_EXCEPTION);
566 if (collapsed) 568 if (collapsed)
567 return emptyString(); 569 return emptyString();
568 Handle<Node> commonAncestor = updatedRange->commonAncestorContainer(ASSERT_N O_EXCEPTION); 570 Handle<Node> commonAncestor = updatedRange->commonAncestorContainer(ASSERT_N O_EXCEPTION);
569 if (!commonAncestor) 571 if (!commonAncestor)
570 return emptyString(); 572 return emptyString();
571 573
572 document->updateLayoutIgnorePendingStylesheets(); 574 document->updateLayoutIgnorePendingStylesheets();
573 575
574 Node* body = enclosingNodeWithTag(firstPositionInNode(commonAncestor), bodyT ag); 576 Handle<Node> body = enclosingNodeWithTag(firstPositionInNode(commonAncestor) , bodyTag);
575 Node* fullySelectedRoot = 0; 577 Handle<Node> fullySelectedRoot;
576 // FIXME: Do this for all fully selected blocks, not just the body. 578 // FIXME: Do this for all fully selected blocks, not just the body.
577 if (body && areRangesEqual(VisibleSelection::selectionFromContentsOfNode(bod y).toNormalizedRange(), range)) 579 if (body && areRangesEqual(VisibleSelection::selectionFromContentsOfNode(bod y.raw()).toNormalizedRange(), range))
578 fullySelectedRoot = body; 580 fullySelectedRoot = body;
579 Node* specialCommonAncestor = highestAncestorToWrapMarkup(updatedRange, shou ldAnnotate, constrainingAncestor); 581 Handle<Node> specialCommonAncestor = adoptRawResult(highestAncestorToWrapMar kup(updatedRange, shouldAnnotate, constrainingAncestor));
580 StyledMarkupAccumulator accumulator(nodes, shouldResolveURLs, shouldAnnotate , updatedRange, specialCommonAncestor); 582 StyledMarkupAccumulator accumulator(nodes, shouldResolveURLs, shouldAnnotate , updatedRange, specialCommonAncestor.raw());
581 Handle<Node> pastEnd = updatedRange->pastLastNode(); 583 Handle<Node> pastEnd = updatedRange->pastLastNode();
582 584
583 Handle<Node> startNode = updatedRange->firstNode(); 585 Handle<Node> startNode = updatedRange->firstNode();
584 VisiblePosition visibleStart(updatedRange->startPosition(), VP_DEFAULT_AFFIN ITY); 586 VisiblePosition visibleStart(updatedRange->startPosition(), VP_DEFAULT_AFFIN ITY);
585 VisiblePosition visibleEnd(updatedRange->endPosition(), VP_DEFAULT_AFFINITY) ; 587 VisiblePosition visibleEnd(updatedRange->endPosition(), VP_DEFAULT_AFFINITY) ;
586 if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter( visibleStart)) { 588 if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter( visibleStart)) {
587 if (visibleStart == visibleEnd.previous()) 589 if (visibleStart == visibleEnd.previous())
588 return interchangeNewlineString; 590 return interchangeNewlineString;
589 591
590 accumulator.appendString(interchangeNewlineString); 592 accumulator.appendString(interchangeNewlineString);
591 startNode = visibleStart.next().deepEquivalent().deprecatedNode(); 593 startNode = visibleStart.next().deepEquivalent().deprecatedNode();
592 594
593 if (pastEnd && Range::compareBoundaryPoints(startNode, 0, pastEnd, 0, AS SERT_NO_EXCEPTION) >= 0) 595 if (pastEnd && Range::compareBoundaryPoints(startNode, 0, pastEnd, 0, AS SERT_NO_EXCEPTION) >= 0)
594 return interchangeNewlineString; 596 return interchangeNewlineString;
595 } 597 }
596 598
597 Node* lastClosed = accumulator.serializeNodes(startNode.raw(), pastEnd.raw() ); 599 Node* lastClosed = accumulator.serializeNodes(startNode.raw(), pastEnd.raw() );
598 600
599 if (specialCommonAncestor && lastClosed) { 601 if (specialCommonAncestor && lastClosed) {
600 HandleScope scope; 602 HandleScope scope;
601 // Also include all of the ancestors of lastClosed up to this special an cestor. 603 // Also include all of the ancestors of lastClosed up to this special an cestor.
602 for (Handle<ContainerNode> ancestor = lastClosed->parentNode(); ancestor ; ancestor = ancestor->parentNode()) { 604 for (Handle<ContainerNode> ancestor = lastClosed->parentNode(); ancestor ; ancestor = ancestor->parentNode()) {
603 HandleScope scope; 605 HandleScope scope;
604 if (ancestor == fullySelectedRoot && !convertBlocksToInlines) { 606 if (ancestor == fullySelectedRoot && !convertBlocksToInlines) {
605 RefPtr<EditingStyle> fullySelectedRootStyle = styleFromMatchedRu lesAndInlineDecl(fullySelectedRoot); 607 RefPtr<EditingStyle> fullySelectedRootStyle = styleFromMatchedRu lesAndInlineDecl(fullySelectedRoot.raw());
606 608
607 // Bring the background attribute over, but not as an attribute because a background attribute on a div 609 // Bring the background attribute over, but not as an attribute because a background attribute on a div
608 // appears to have no effect. 610 // appears to have no effect.
609 if ((!fullySelectedRootStyle || !fullySelectedRootStyle->style() || !fullySelectedRootStyle->style()->getPropertyCSSValue(CSSPropertyBackgroundI mage)) 611 if ((!fullySelectedRootStyle || !fullySelectedRootStyle->style() || !fullySelectedRootStyle->style()->getPropertyCSSValue(CSSPropertyBackgroundI mage))
610 && toElement(fullySelectedRoot)->hasAttribute(backgroundAttr )) 612 && toElement(fullySelectedRoot)->hasAttribute(backgroundAttr ))
611 fullySelectedRootStyle->style()->setProperty(CSSPropertyBack groundImage, "url('" + toElement(fullySelectedRoot)->getAttribute(backgroundAttr ) + "')"); 613 fullySelectedRootStyle->style()->setProperty(CSSPropertyBack groundImage, "url('" + toElement(fullySelectedRoot)->getAttribute(backgroundAttr ) + "')");
612 614
613 if (fullySelectedRootStyle->style()) { 615 if (fullySelectedRootStyle->style()) {
614 // Reset the CSS properties to avoid an assertion error in a ddStyleMarkup(). 616 // Reset the CSS properties to avoid an assertion error in a ddStyleMarkup().
615 // This assertion is caused at least when we select all text of a <body> element whose 617 // This assertion is caused at least when we select all text of a <body> element whose
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 RefPtr<Node> nodeBeforeContext; 732 RefPtr<Node> nodeBeforeContext;
731 RefPtr<Node> nodeAfterContext; 733 RefPtr<Node> nodeAfterContext;
732 if (!findNodesSurroundingContext(taggedDocument, nodeBeforeContext, nodeAfte rContext)) 734 if (!findNodesSurroundingContext(taggedDocument, nodeBeforeContext, nodeAfte rContext))
733 return nullptr; 735 return nullptr;
734 736
735 Handle<Range> range = Range::create(taggedDocument, 737 Handle<Range> range = Range::create(taggedDocument,
736 positionAfterNode(adoptRawResult(nodeBeforeContext.get())).parentAnchore dEquivalent(), 738 positionAfterNode(adoptRawResult(nodeBeforeContext.get())).parentAnchore dEquivalent(),
737 positionBeforeNode(adoptRawResult(nodeAfterContext.get())).parentAnchore dEquivalent()); 739 positionBeforeNode(adoptRawResult(nodeAfterContext.get())).parentAnchore dEquivalent());
738 740
739 Handle<Node> commonAncestor = range->commonAncestorContainer(ASSERT_NO_EXCEP TION); 741 Handle<Node> commonAncestor = range->commonAncestorContainer(ASSERT_NO_EXCEP TION);
740 Node* specialCommonAncestor = ancestorToRetainStructureAndAppearanceWithNoRe nderer(commonAncestor.raw()); 742 Handle<Node> specialCommonAncestor = ancestorToRetainStructureAndAppearanceW ithNoRenderer(commonAncestor);
741 743
742 // When there's a special common ancestor outside of the fragment, we must i nclude it as well to 744 // When there's a special common ancestor outside of the fragment, we must i nclude it as well to
743 // preserve the structure and appearance of the fragment. For example, if th e fragment contains 745 // preserve the structure and appearance of the fragment. For example, if th e fragment contains
744 // TD, we need to include the enclosing TABLE tag as well. 746 // TD, we need to include the enclosing TABLE tag as well.
745 Handle<DocumentFragment> fragment = DocumentFragment::create(document); 747 Handle<DocumentFragment> fragment = DocumentFragment::create(document);
746 if (specialCommonAncestor) 748 if (specialCommonAncestor)
747 fragment->appendChild(adoptRawResult(specialCommonAncestor), ASSERT_NO_E XCEPTION); 749 fragment->appendChild(specialCommonAncestor, ASSERT_NO_EXCEPTION);
748 else 750 else
749 fragment->takeAllChildrenFrom(toContainerNode(commonAncestor)); 751 fragment->takeAllChildrenFrom(toContainerNode(commonAncestor));
750 752
751 trimFragment(fragment, nodeBeforeContext.get(), nodeAfterContext.get()); 753 trimFragment(fragment, nodeBeforeContext.get(), nodeAfterContext.get());
752 754
753 return fragment; 755 return fragment;
754 } 756 }
755 757
756 String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, Vector<QualifiedName>* tagNamesToSkip) 758 String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, Vector<QualifiedName>* tagNamesToSkip)
757 { 759 {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 } 806 }
805 807
806 bool isPlainTextMarkup(Node *node) 808 bool isPlainTextMarkup(Node *node)
807 { 809 {
808 if (!node->isElementNode() || !node->hasTagName(divTag) || toElement(node)-> hasAttributes()) 810 if (!node->isElementNode() || !node->hasTagName(divTag) || toElement(node)-> hasAttributes())
809 return false; 811 return false;
810 812
811 if (node->childNodeCount() == 1 && (node->firstChild()->isTextNode() || (nod e->firstChild()->firstChild()))) 813 if (node->childNodeCount() == 1 && (node->firstChild()->isTextNode() || (nod e->firstChild()->firstChild())))
812 return true; 814 return true;
813 815
814 return (node->childNodeCount() == 2 && isTabSpanTextNode(node->firstChild()- >firstChild().handle().raw()) && node->firstChild()->nextSibling()->isTextNode() ); 816 return (node->childNodeCount() == 2 && isTabSpanTextNode(node->firstChild()- >firstChild()) && node->firstChild()->nextSibling()->isTextNode());
815 } 817 }
816 818
817 Result<DocumentFragment> createFragmentFromText(const Handle<Range>& context, co nst String& text) 819 Result<DocumentFragment> createFragmentFromText(const Handle<Range>& context, co nst String& text)
818 { 820 {
819 if (!context) 821 if (!context)
820 return nullptr; 822 return nullptr;
821 823
822 Handle<Node> styleNode = context->firstNode(); 824 Handle<Node> styleNode = context->firstNode();
823 if (!styleNode) { 825 if (!styleNode) {
824 styleNode = context->startPosition().deprecatedNode(); 826 styleNode = context->startPosition().deprecatedNode();
(...skipping 22 matching lines...) Expand all
847 return fragment; 849 return fragment;
848 } 850 }
849 851
850 // A string with no newlines gets added inline, rather than being put into a paragraph. 852 // A string with no newlines gets added inline, rather than being put into a paragraph.
851 if (string.find('\n') == notFound) { 853 if (string.find('\n') == notFound) {
852 fillContainerFromString(fragment, string); 854 fillContainerFromString(fragment, string);
853 return fragment; 855 return fragment;
854 } 856 }
855 857
856 // Break string into paragraphs. Extra line breaks turn into empty paragraph s. 858 // Break string into paragraphs. Extra line breaks turn into empty paragraph s.
857 Handle<Node> blockNode = enclosingBlock(context->firstNode().handle().raw()) ; 859 Handle<Node> blockNode = enclosingBlock(context->firstNode());
858 Handle<Element> block = toElement(blockNode); 860 Handle<Element> block = toElement(blockNode);
859 bool useClonesOfEnclosingBlock = blockNode 861 bool useClonesOfEnclosingBlock = blockNode
860 && blockNode->isElementNode() 862 && blockNode->isElementNode()
861 && !block->hasTagName(bodyTag) 863 && !block->hasTagName(bodyTag)
862 && !block->hasTagName(htmlTag) 864 && !block->hasTagName(htmlTag)
863 && block != editableRootForPosition(context->startPosition()); 865 && block != editableRootForPosition(context->startPosition());
864 bool useLineBreak = enclosingTextFormControl(context->startPosition()); 866 bool useLineBreak = enclosingTextFormControl(context->startPosition());
865 867
866 Vector<String> list; 868 Vector<String> list;
867 string.split('\n', true, list); // true gets us empty strings in the list 869 string.split('\n', true, list); // true gets us empty strings in the list
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 if (hasOneChild(containerNode)) { 1104 if (hasOneChild(containerNode)) {
1103 containerNode->replaceChild(textNode, containerNode->firstChild(), ec); 1105 containerNode->replaceChild(textNode, containerNode->firstChild(), ec);
1104 return; 1106 return;
1105 } 1107 }
1106 1108
1107 containerNode->removeChildren(); 1109 containerNode->removeChildren();
1108 containerNode->appendChild(textNode, ec); 1110 containerNode->appendChild(textNode, ec);
1109 } 1111 }
1110 1112
1111 } 1113 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698