OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> | 2 * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> |
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Rob Buis <buis@kde.org> | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Rob Buis <buis@kde.org> |
4 * Copyright (C) 2007 Apple Inc. All rights reserved. | 4 * Copyright (C) 2007 Apple Inc. All rights reserved. |
5 * Copyright (C) 2014 Google, Inc. | 5 * Copyright (C) 2014 Google, Inc. |
6 * | 6 * |
7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 { | 92 { |
93 // FIXME: This method doesn't follow the spec and is basically untested. Par
ent documents are not considered here. | 93 // FIXME: This method doesn't follow the spec and is basically untested. Par
ent documents are not considered here. |
94 // As we have no test coverage for this, we're going to disable it completly
for now. | 94 // As we have no test coverage for this, we're going to disable it completly
for now. |
95 return SVGRectTearOff::create(SVGRect::create(), 0, PropertyIsNotAnimVal); | 95 return SVGRectTearOff::create(SVGRect::create(), 0, PropertyIsNotAnimVal); |
96 } | 96 } |
97 | 97 |
98 SVGViewSpec* SVGSVGElement::currentView() | 98 SVGViewSpec* SVGSVGElement::currentView() |
99 { | 99 { |
100 if (!m_viewSpec) | 100 if (!m_viewSpec) |
101 m_viewSpec = SVGViewSpec::create(this); | 101 m_viewSpec = SVGViewSpec::create(this); |
102 return m_viewSpec.get(); | 102 return m_viewSpec; |
103 } | 103 } |
104 | 104 |
105 float SVGSVGElement::currentScale() const | 105 float SVGSVGElement::currentScale() const |
106 { | 106 { |
107 if (!isConnected() || !isOutermostSVGSVGElement()) | 107 if (!isConnected() || !isOutermostSVGSVGElement()) |
108 return 1; | 108 return 1; |
109 | 109 |
110 return m_currentScale; | 110 return m_currentScale; |
111 } | 111 } |
112 | 112 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 void SVGSVGElement::updateUserTransform() | 154 void SVGSVGElement::updateUserTransform() |
155 { | 155 { |
156 if (LayoutObject* object = layoutObject()) | 156 if (LayoutObject* object = layoutObject()) |
157 object->setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason:
:Unknown); | 157 object->setNeedsLayoutAndFullPaintInvalidation(LayoutInvalidationReason:
:Unknown); |
158 } | 158 } |
159 | 159 |
160 bool SVGSVGElement::zoomAndPanEnabled() const | 160 bool SVGSVGElement::zoomAndPanEnabled() const |
161 { | 161 { |
162 const SVGZoomAndPan* currentViewSpec = this; | 162 const SVGZoomAndPan* currentViewSpec = this; |
163 if (m_useCurrentView) | 163 if (m_useCurrentView) |
164 currentViewSpec = m_viewSpec.get(); | 164 currentViewSpec = m_viewSpec; |
165 return currentViewSpec && currentViewSpec->zoomAndPan() == SVGZoomAndPanMagn
ify; | 165 DCHECK(currentViewSpec); |
| 166 return currentViewSpec->zoomAndPan() == SVGZoomAndPanMagnify; |
166 } | 167 } |
167 | 168 |
168 void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString
& oldValue, const AtomicString& value) | 169 void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString
& oldValue, const AtomicString& value) |
169 { | 170 { |
170 if (!nearestViewportElement()) { | 171 if (!nearestViewportElement()) { |
171 bool setListener = true; | 172 bool setListener = true; |
172 | 173 |
173 // Only handle events if we're the outermost <svg> element | 174 // Only handle events if we're the outermost <svg> element |
174 if (name == HTMLNames::onunloadAttr) { | 175 if (name == HTMLNames::onunloadAttr) { |
175 document().setWindowAttributeEventListener(EventTypeNames::unload, c
reateAttributeEventListener(document().frame(), name, value, eventParameterName(
))); | 176 document().setWindowAttributeEventListener(EventTypeNames::unload, c
reateAttributeEventListener(document().frame(), name, value, eventParameterName(
))); |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 bool SVGSVGElement::selfHasRelativeLengths() const | 562 bool SVGSVGElement::selfHasRelativeLengths() const |
562 { | 563 { |
563 return m_x->currentValue()->isRelative() | 564 return m_x->currentValue()->isRelative() |
564 || m_y->currentValue()->isRelative() | 565 || m_y->currentValue()->isRelative() |
565 || m_width->currentValue()->isRelative() | 566 || m_width->currentValue()->isRelative() |
566 || m_height->currentValue()->isRelative(); | 567 || m_height->currentValue()->isRelative(); |
567 } | 568 } |
568 | 569 |
569 FloatRect SVGSVGElement::currentViewBoxRect() const | 570 FloatRect SVGSVGElement::currentViewBoxRect() const |
570 { | 571 { |
571 if (m_useCurrentView) | 572 if (m_useCurrentView) { |
572 return m_viewSpec ? m_viewSpec->viewBox()->currentValue()->value() : Flo
atRect(); | 573 DCHECK(m_viewSpec); |
| 574 return m_viewSpec->viewBox()->currentValue()->value(); |
| 575 } |
573 | 576 |
574 FloatRect useViewBox = viewBox()->currentValue()->value(); | 577 FloatRect useViewBox = viewBox()->currentValue()->value(); |
575 if (!useViewBox.isEmpty()) | 578 if (!useViewBox.isEmpty()) |
576 return useViewBox; | 579 return useViewBox; |
577 if (!layoutObject() || !layoutObject()->isSVGRoot()) | 580 if (!layoutObject() || !layoutObject()->isSVGRoot()) |
578 return FloatRect(); | 581 return FloatRect(); |
579 if (!toLayoutSVGRoot(layoutObject())->isEmbeddedThroughSVGImage()) | 582 if (!toLayoutSVGRoot(layoutObject())->isEmbeddedThroughSVGImage()) |
580 return FloatRect(); | 583 return FloatRect(); |
581 | 584 |
582 // If no viewBox is specified but non-relative width/height values, then we | 585 // If no viewBox is specified but non-relative width/height values, then we |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 { | 624 { |
622 if (height()->currentValue()->typeWithCalcResolved() == CSSPrimitiveValue::U
nitType::Percentage) | 625 if (height()->currentValue()->typeWithCalcResolved() == CSSPrimitiveValue::U
nitType::Percentage) |
623 return 0; | 626 return 0; |
624 | 627 |
625 SVGLengthContext lengthContext(this); | 628 SVGLengthContext lengthContext(this); |
626 return height()->currentValue()->value(lengthContext); | 629 return height()->currentValue()->value(lengthContext); |
627 } | 630 } |
628 | 631 |
629 AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float vie
wHeight) const | 632 AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float vie
wHeight) const |
630 { | 633 { |
631 if (!m_useCurrentView || !m_viewSpec) | 634 if (!m_useCurrentView) |
632 return SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), pre
serveAspectRatio()->currentValue(), viewWidth, viewHeight); | 635 return SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), pre
serveAspectRatio()->currentValue(), viewWidth, viewHeight); |
| 636 DCHECK(m_viewSpec); |
633 | 637 |
634 AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform(currentViewBox
Rect(), m_viewSpec->preserveAspectRatio()->currentValue(), viewWidth, viewHeight
); | 638 AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform(currentViewBox
Rect(), m_viewSpec->preserveAspectRatio()->currentValue(), viewWidth, viewHeight
); |
635 SVGTransformList* transformList = m_viewSpec->transform(); | 639 SVGTransformList* transformList = m_viewSpec->transform(); |
636 if (transformList->isEmpty()) | 640 if (transformList->isEmpty()) |
637 return ctm; | 641 return ctm; |
638 | 642 |
639 AffineTransform transform; | 643 AffineTransform transform; |
640 if (transformList->concatenate(transform)) | 644 if (transformList->concatenate(transform)) |
641 ctm *= transform; | 645 ctm *= transform; |
642 | 646 |
643 return ctm; | 647 return ctm; |
644 } | 648 } |
645 | 649 |
646 void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element*
anchorNode) | 650 void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element*
anchorNode) |
647 { | 651 { |
648 LayoutObject* layoutObject = this->layoutObject(); | 652 if (m_viewSpec) |
649 SVGViewSpec* view = m_viewSpec.get(); | 653 m_viewSpec->reset(); |
650 if (view) | |
651 view->reset(); | |
652 | 654 |
653 bool hadUseCurrentView = m_useCurrentView; | 655 // If we previously had a view, we need to layout again, regardless of the |
| 656 // state after setting. |
| 657 bool needsViewUpdate = m_useCurrentView; |
654 m_useCurrentView = false; | 658 m_useCurrentView = false; |
655 | 659 |
656 if (fragmentIdentifier.startsWith("svgView(")) { | 660 if (fragmentIdentifier.startsWith("svgView(")) { |
657 if (!view) | 661 SVGViewSpec* view = currentView(); // Ensure the SVGViewSpec has been cr
eated. |
658 view = currentView(); // Create the SVGViewSpec. | |
659 | 662 |
660 view->inheritViewAttributesFromElement(this); | 663 view->inheritViewAttributesFromElement(this); |
661 | 664 |
662 if (view->parseViewSpec(fragmentIdentifier)) { | 665 if (view->parseViewSpec(fragmentIdentifier)) { |
663 UseCounter::count(document(), UseCounter::SVGSVGElementFragmentSVGVi
ew); | 666 UseCounter::count(document(), UseCounter::SVGSVGElementFragmentSVGVi
ew); |
664 m_useCurrentView = true; | 667 m_useCurrentView = true; |
| 668 needsViewUpdate = true; |
665 } else { | 669 } else { |
666 view->reset(); | 670 view->reset(); |
667 } | 671 } |
668 | 672 } else if (isSVGViewElement(anchorNode)) { |
669 if (layoutObject && (hadUseCurrentView || m_useCurrentView)) | 673 // Spec: If the SVG fragment identifier addresses a 'view' element |
670 markForLayoutAndParentResourceInvalidation(layoutObject); | 674 // within an SVG document (e.g., MyDrawing.svg#MyView or |
671 return; | 675 // MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor |
672 } | 676 // 'svg' element is displayed in the viewport. Any view specification |
673 | 677 // attributes included on the given 'view' element override the |
674 // Spec: If the SVG fragment identifier addresses a 'view' element within an
SVG document (e.g., MyDrawing.svg#MyView | 678 // corresponding view specification attributes on the closest ancestor |
675 // or MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor 'svg'
element is displayed in the viewport. | 679 // 'svg' element. |
676 // Any view specification attributes included on the given 'view' element ov
erride the corresponding view specification | 680 // TODO(ed): The spec text above is a bit unclear. |
677 // attributes on the closest ancestor 'svg' element. | 681 // Should the transform from outermost svg to nested svg be applied to |
678 // TODO(ed): The spec text above is a bit unclear. | 682 // "display" the inner svg in the viewport, then let the view element |
679 // Should the transform from outermost svg to nested svg be applied to "disp
lay" | 683 // override the inner svg's view specification attributes. Should it |
680 // the inner svg in the viewport, then let the view element override the inn
er | 684 // fill/override the outer viewport? |
681 // svg's view specification attributes. Should it fill/override the outer vi
ewport? | |
682 if (isSVGViewElement(anchorNode)) { | |
683 SVGViewElement& viewElement = toSVGViewElement(*anchorNode); | 685 SVGViewElement& viewElement = toSVGViewElement(*anchorNode); |
684 | 686 |
685 if (SVGSVGElement* svg = viewElement.ownerSVGElement()) { | 687 if (SVGSVGElement* svg = viewElement.ownerSVGElement()) { |
686 svg->inheritViewAttributes(&viewElement); | 688 svg->inheritViewAttributes(&viewElement); |
687 | 689 |
688 if (LayoutObject* layoutObject = svg->layoutObject()) | 690 if (LayoutObject* layoutObject = svg->layoutObject()) |
689 markForLayoutAndParentResourceInvalidation(layoutObject); | 691 markForLayoutAndParentResourceInvalidation(layoutObject); |
690 | 692 |
691 return; | 693 return; |
692 } | 694 } |
693 } | 695 } |
694 | 696 |
695 // If we previously had a view and didn't get a new one, we need to | 697 LayoutObject* layoutObject = this->layoutObject(); |
696 // layout again. | 698 if (layoutObject && needsViewUpdate) |
697 if (layoutObject && hadUseCurrentView) | |
698 markForLayoutAndParentResourceInvalidation(layoutObject); | 699 markForLayoutAndParentResourceInvalidation(layoutObject); |
699 | 700 |
| 701 // If m_useCurrentView is true we should have a view-spec. |
| 702 DCHECK(!m_useCurrentView || m_viewSpec); |
| 703 |
700 // FIXME: We need to decide which <svg> to focus on, and zoom to it. | 704 // FIXME: We need to decide which <svg> to focus on, and zoom to it. |
701 // FIXME: We need to actually "highlight" the viewTarget(s). | 705 // FIXME: We need to actually "highlight" the viewTarget(s). |
702 } | 706 } |
703 | 707 |
704 void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement) | 708 void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement) |
705 { | 709 { |
706 SVGViewSpec* view = currentView(); | 710 SVGViewSpec* view = currentView(); |
707 m_useCurrentView = true; | 711 m_useCurrentView = true; |
708 UseCounter::count(document(), UseCounter::SVGSVGElementFragmentSVGViewElemen
t); | 712 UseCounter::count(document(), UseCounter::SVGSVGElementFragmentSVGViewElemen
t); |
709 view->inheritViewAttributesFromElement(this); | 713 view->inheritViewAttributesFromElement(this); |
710 view->inheritViewAttributesFromElement(viewElement); | 714 view->inheritViewAttributesFromElement(viewElement); |
| 715 DCHECK(!m_useCurrentView || m_viewSpec); |
711 } | 716 } |
712 | 717 |
713 void SVGSVGElement::finishParsingChildren() | 718 void SVGSVGElement::finishParsingChildren() |
714 { | 719 { |
715 SVGGraphicsElement::finishParsingChildren(); | 720 SVGGraphicsElement::finishParsingChildren(); |
716 | 721 |
717 // The outermost SVGSVGElement SVGLoad event is fired through | 722 // The outermost SVGSVGElement SVGLoad event is fired through |
718 // LocalDOMWindow::dispatchWindowLoadEvent. | 723 // LocalDOMWindow::dispatchWindowLoadEvent. |
719 if (isOutermostSVGSVGElement()) | 724 if (isOutermostSVGSVGElement()) |
720 return; | 725 return; |
(...skipping 10 matching lines...) Expand all Loading... |
731 visitor->trace(m_width); | 736 visitor->trace(m_width); |
732 visitor->trace(m_height); | 737 visitor->trace(m_height); |
733 visitor->trace(m_translation); | 738 visitor->trace(m_translation); |
734 visitor->trace(m_timeContainer); | 739 visitor->trace(m_timeContainer); |
735 visitor->trace(m_viewSpec); | 740 visitor->trace(m_viewSpec); |
736 SVGGraphicsElement::trace(visitor); | 741 SVGGraphicsElement::trace(visitor); |
737 SVGFitToViewBox::trace(visitor); | 742 SVGFitToViewBox::trace(visitor); |
738 } | 743 } |
739 | 744 |
740 } // namespace blink | 745 } // namespace blink |
OLD | NEW |